From 6b4a8b2a2f0f2b01309e676a0c7b603a8b800a3c Mon Sep 17 00:00:00 2001 From: nyanmisaka Date: Mon, 25 May 2026 19:01:52 +0800 Subject: [PATCH] New upstream version 7.1.4 Signed-off-by: nyanmisaka --- .forgejo/pre-commit/config.yaml | 23 ++ .forgejo/workflows/lint.yml | 29 +++ .forgejo/workflows/test.yml | 80 ++++++ COPYING.LGPLv2.1 | 18 +- Changelog | 242 ++++++++++++++++++ RELEASE | 2 +- VERSION | 2 +- configure | 18 +- doc/APIchanges | 3 + doc/Doxyfile | 2 +- doc/build_system.txt | 1 - doc/fate_config.sh.template | 5 + doc/infra.txt | 1 - doc/mailing-list-faq.texi | 2 +- doc/nut.texi | 1 - doc/texi2pod.pl | 0 doc/texidep.pl | 0 doc/undefined.txt | 1 - fftools/ffmpeg.h | 2 + fftools/ffmpeg_demux.c | 57 ++++- fftools/ffmpeg_filter.c | 21 +- fftools/ffmpeg_opt.c | 10 + libavcodec/Makefile | 2 +- libavcodec/aac/aacdec.c | 6 + libavcodec/aac/aacdec_usac.c | 31 ++- libavcodec/aarch64/hpeldsp_neon.S | 58 ++--- libavcodec/adpcm.c | 2 + libavcodec/alsdec.c | 17 +- libavcodec/aom_film_grain.c | 5 +- libavcodec/arm/int_neon.S | 1 - libavcodec/av1dec.c | 16 +- libavcodec/bmp.c | 2 +- libavcodec/cbs_h266_syntax_template.c | 23 +- libavcodec/cfhd.c | 9 +- libavcodec/cfhd.h | 9 + libavcodec/cfhdenc.c | 12 +- libavcodec/cljrdec.c | 1 - libavcodec/dca_xll.c | 20 +- libavcodec/decode.c | 52 ++-- libavcodec/decode.h | 10 +- libavcodec/dfpwmdec.c | 5 +- libavcodec/dv_profile.c | 1 - libavcodec/dvdsub_parser.c | 2 +- libavcodec/dxv.c | 7 +- libavcodec/escape130.c | 2 +- libavcodec/exr.c | 21 +- libavcodec/ffv1_template.c | 1 - libavcodec/ffv1enc_template.c | 1 - libavcodec/flashsv.c | 3 + libavcodec/golomb.h | 4 +- libavcodec/h2645_sei.c | 2 +- libavcodec/h264_direct.c | 34 +-- libavcodec/h264_mc_template.c | 1 - libavcodec/h264_parser.c | 11 +- libavcodec/h264_refs.c | 6 +- libavcodec/h264_slice.c | 9 +- libavcodec/hdrdec.c | 3 + libavcodec/hevc/cabac.c | 1 - libavcodec/hevc/ps.c | 7 + libavcodec/hevc/refs.c | 5 +- libavcodec/hevc/sei.c | 4 +- libavcodec/hevc/sei.h | 4 +- libavcodec/imgconvert.c | 1 - libavcodec/imm5.c | 2 + libavcodec/interplayacm.c | 3 + libavcodec/jpeg2000dec.c | 11 +- libavcodec/jpeg2000htdec.c | 12 +- libavcodec/lcevcdec.c | 128 +++++----- libavcodec/lcldec.c | 4 +- libavcodec/libsvtav1.c | 4 + libavcodec/lzf.c | 13 +- libavcodec/magicyuv.c | 3 +- libavcodec/mdec.c | 3 + libavcodec/mjpegdec.c | 10 +- libavcodec/mpegaudiodsp_template.c | 1 - libavcodec/mpegaudioenc_template.c | 1 - libavcodec/mpegvideo_enc.c | 17 +- libavcodec/mpv_reconstruct_mb_template.c | 1 - libavcodec/msmpeg4.c | 1 - libavcodec/notchlc.c | 6 +- libavcodec/omx.c | 5 + libavcodec/opus/parse.c | 1 - libavcodec/pdvdec.c | 3 + libavcodec/pnmdec.c | 3 + libavcodec/qdm2.c | 2 + libavcodec/ralf.c | 1 + libavcodec/rasc.c | 10 +- libavcodec/snow_dwt.c | 2 - libavcodec/snowenc.c | 8 +- libavcodec/svq1dec.c | 5 + libavcodec/tableprint_vlc.h | 2 +- libavcodec/tdsc.c | 10 +- libavcodec/tmv.c | 6 +- libavcodec/utils.c | 20 +- libavcodec/videotoolbox_vp9.c | 2 +- libavcodec/videotoolboxenc.c | 2 +- libavcodec/vp3.c | 7 +- libavcodec/vp9.c | 18 +- libavcodec/vvc/intra.c | 1 - libavcodec/wmaenc.c | 4 +- libavcodec/x86/fmtconvert.asm | 1 - libavcodec/x86/mpegvideoencdsp.asm | 1 - libavcodec/xxan.c | 2 +- libavcodec/zmbv.c | 14 +- libavdevice/gdigrab.c | 2 +- libavfilter/aarch64/vf_bwdif_init_aarch64.c | 1 - libavfilter/af_amerge.c | 18 +- libavfilter/af_lv2.c | 6 + libavfilter/af_pan.c | 4 +- libavfilter/avf_showcwt.c | 8 +- libavfilter/buffersrc.c | 10 + libavfilter/buffersrc.h | 8 + libavfilter/convolution.h | 8 +- libavfilter/dnn/dnn_interface.c | 1 - libavfilter/framesync.c | 2 +- libavfilter/perlin.c | 1 - libavfilter/qp_table.c | 1 - libavfilter/scale_eval.c | 13 +- libavfilter/scene_sad.c | 1 - libavfilter/stack_internal.h | 6 + libavfilter/textutils.c | 1 - libavfilter/version.h | 2 +- libavfilter/vf_bwdif.c | 19 +- libavfilter/vf_codecview.c | 17 +- libavfilter/vf_convolution.c | 36 ++- libavfilter/vf_drawtext.c | 12 +- libavfilter/vf_find_rect.c | 55 +++-- libavfilter/vf_kerndeint.c | 6 + libavfilter/vf_lcevc.c | 25 +- libavfilter/vf_libopencv.c | 2 +- libavfilter/vf_neighbor_opencl.c | 3 + libavfilter/vf_overlay_cuda.cu | 1 - libavfilter/vf_quirc.c | 1 - libavfilter/vf_scale.c | 6 +- libavfilter/vf_ssim360.c | 12 +- libavfilter/vf_stack.c | 38 ++- libavfilter/vf_v360.c | 2 +- libavfilter/vf_zscale.c | 13 +- libavformat/avidec.c | 10 +- libavformat/cafdec.c | 6 + libavformat/concat.c | 12 + libavformat/dash.c | 2 - libavformat/dashdec.c | 84 ++++--- libavformat/demux.c | 28 ++- libavformat/dhav.c | 4 +- libavformat/dss.c | 5 +- libavformat/dtshddec.c | 7 +- libavformat/flac_picture.c | 6 +- libavformat/flvdec.c | 4 + libavformat/g726.c | 1 - libavformat/hls.c | 11 +- libavformat/hls_sample_encryption.c | 1 + libavformat/hls_sample_encryption.h | 3 +- libavformat/hlsplaylist.c | 1 - libavformat/http.c | 23 +- libavformat/iamf_parse.c | 10 +- libavformat/iamf_reader.c | 15 +- libavformat/iamf_reader.h | 2 +- libavformat/iamf_writer.c | 21 +- libavformat/iamfdec.c | 2 +- libavformat/icodec.c | 2 +- libavformat/iff.c | 4 +- libavformat/img2dec.c | 15 +- libavformat/img2enc.c | 5 + libavformat/isom.h | 1 + libavformat/lrcdec.c | 2 +- libavformat/matroskadec.c | 8 + libavformat/mlvdec.c | 8 +- libavformat/mov.c | 119 +++++++-- libavformat/mpegts.c | 9 +- libavformat/mpegtsenc.c | 7 + libavformat/pcm.c | 10 +- libavformat/rdt.c | 1 - libavformat/rsd.c | 7 +- libavformat/rtmpproto.c | 58 +++-- libavformat/rtpdec_jpeg.c | 6 + libavformat/rtpdec_latm.c | 6 +- libavformat/rtpdec_mpeg4.c | 2 +- libavformat/rtpdec_qdm2.c | 10 +- libavformat/rtpenc.c | 2 +- libavformat/rtsp.c | 27 ++- libavformat/rtspdec.c | 8 +- libavformat/scd.c | 3 +- libavformat/segafilm.c | 2 +- libavformat/tests/movenc.c | 54 ++--- libavformat/version.h | 2 +- libavformat/vividas.c | 8 +- libavformat/wavdec.c | 3 +- libavformat/wtvdec.c | 3 +- libavformat/xwma.c | 2 +- libavformat/yuv4mpegenc.c | 3 + libavutil/aes.c | 1 - libavutil/bswap.h | 2 +- libavutil/dovi_meta.h | 4 + libavutil/eval.c | 15 ++ libavutil/hwcontext_cuda_internal.h | 1 - libavutil/hwcontext_d3d12va.c | 4 +- libavutil/hwcontext_qsv.h | 1 - libavutil/samplefmt.h | 3 +- libavutil/tests/blowfish.c | 1 - libavutil/timecode.c | 11 +- libswresample/aarch64/resample.S | 8 +- libswresample/rematrix.c | 5 +- libswresample/resample_template.c | 17 +- libswresample/soxr_resample.c | 1 - libswresample/swresample.c | 32 ++- libswresample/swresample_frame.c | 1 - libswresample/swresample_internal.h | 1 + libswresample/version.c | 1 - libswscale/aarch64/yuv2rgb_neon.S | 10 +- libswscale/gamma.c | 1 - libswscale/output.c | 26 +- libswscale/rgb2rgb_template.c | 4 +- libswscale/swscale_unscaled.c | 6 +- libswscale/utils.c | 59 +++-- libswscale/vscale.c | 2 - tests/extended.ffconcat | 1 - tests/fate-run.sh | 13 +- tests/fate/ffmpeg.mak | 5 + tests/fate/ffprobe.mak | 1 - tests/fate/lossless-audio.mak | 1 - tests/ref/fate/filter-bwdif-mode0 | 2 +- tests/ref/fate/filter-bwdif-mode1 | 2 +- tests/ref/fate/filter-bwdif10 | 2 +- tests/ref/fate/mov-mp4-iamf-7_1_4-video-last | 42 ++-- tests/simple1.ffconcat | 1 - tests/simple2.ffconcat | 1 - tools/check_arm_indent.sh | 55 +++++ tools/indent_arm_assembly.pl | 243 +++++++++++++++++++ 229 files changed, 2165 insertions(+), 698 deletions(-) create mode 100644 .forgejo/pre-commit/config.yaml create mode 100644 .forgejo/workflows/lint.yml create mode 100644 .forgejo/workflows/test.yml mode change 100644 => 100755 doc/texi2pod.pl mode change 100644 => 100755 doc/texidep.pl create mode 100755 tools/check_arm_indent.sh create mode 100755 tools/indent_arm_assembly.pl diff --git a/.forgejo/pre-commit/config.yaml b/.forgejo/pre-commit/config.yaml new file mode 100644 index 000000000..8ce116dae --- /dev/null +++ b/.forgejo/pre-commit/config.yaml @@ -0,0 +1,23 @@ +exclude: ^tests/ref/ + +repos: +- repo: https://github.com/pre-commit/pre-commit-hooks + rev: v5.0.0 + hooks: + - id: check-case-conflict + - id: check-executables-have-shebangs + - id: check-illegal-windows-names + - id: check-shebang-scripts-are-executable + - id: check-yaml + - id: end-of-file-fixer + - id: fix-byte-order-marker + - id: mixed-line-ending + - id: trailing-whitespace +- repo: local + hooks: + - id: aarch64-asm-indent + name: fix aarch64 assembly indentation + files: ^.*/aarch64/.*\.S$ + language: script + entry: ./tools/check_arm_indent.sh --apply + pass_filenames: false diff --git a/.forgejo/workflows/lint.yml b/.forgejo/workflows/lint.yml new file mode 100644 index 000000000..da9c82948 --- /dev/null +++ b/.forgejo/workflows/lint.yml @@ -0,0 +1,29 @@ +name: Lint + +on: + push: + branches: + - release/7.1 + pull_request: + +jobs: + lint: + name: Pre-Commit + runs-on: utilities + steps: + - name: Checkout + uses: actions/checkout@v4 + - name: Install pre-commit CI + id: install + run: | + python3 -m venv ~/pre-commit + ~/pre-commit/bin/pip install --upgrade pip setuptools + ~/pre-commit/bin/pip install pre-commit + echo "envhash=$({ python3 --version && cat .forgejo/pre-commit/config.yaml; } | sha256sum | cut -d' ' -f1)" >> $FORGEJO_OUTPUT + - name: Cache + uses: actions/cache@v4 + with: + path: ~/.cache/pre-commit + key: pre-commit-${{ steps.install.outputs.envhash }} + - name: Run pre-commit CI + run: ~/pre-commit/bin/pre-commit run -c .forgejo/pre-commit/config.yaml --show-diff-on-failure --color=always --all-files diff --git a/.forgejo/workflows/test.yml b/.forgejo/workflows/test.yml new file mode 100644 index 000000000..9d263d98d --- /dev/null +++ b/.forgejo/workflows/test.yml @@ -0,0 +1,80 @@ +name: Test + +on: + push: + branches: + - release/7.1 + pull_request: + +jobs: + run_fate: + name: Fate (${{ matrix.runner }}, ${{ matrix.shared }}, ${{ matrix.bits }} bit) + strategy: + fail-fast: false + matrix: + runner: [linux-aarch64] + shared: ['static'] + bits: ['64'] + include: + - runner: linux-amd64 + shared: 'static' + bits: '32' + - runner: linux-amd64 + shared: 'shared' + bits: '64' + runs-on: ${{ matrix.runner }} + steps: + - name: Checkout + uses: actions/checkout@v4 + - name: Configure + run: | + ./configure --enable-gpl --enable-nonfree --enable-memory-poisoning --assert-level=2 \ + $([ "${{ matrix.bits }}" != "32" ] || echo --arch=x86_32 --extra-cflags=-m32 --extra-cxxflags=-m32 --extra-ldflags=-m32) \ + $([ "${{ matrix.shared }}" != "shared" ] || echo --enable-shared --disable-static) \ + || CFGRES=$? && CFGRES=$? + cat ffbuild/config.log + exit $CFGRES + - name: Build + run: make -j$(nproc) + - name: Restore Cached Fate-Suite + id: cache + uses: actions/cache/restore@v4 + with: + path: fate-suite + key: fate-suite + restore-keys: | + fate-suite- + - name: Sync Fate-Suite + id: fate + run: | + make fate-rsync SAMPLES=$PWD/fate-suite + echo "hash=$(find fate-suite -type f -printf "%P %s %T@\n" | sort | sha256sum | cut -d' ' -f1)" >> $FORGEJO_OUTPUT + - name: Cache Fate-Suite + uses: actions/cache/save@v4 + if: ${{ format('fate-suite-{0}', steps.fate.outputs.hash) != steps.cache.outputs.cache-matched-key }} + with: + path: fate-suite + key: fate-suite-${{ steps.fate.outputs.hash }} + - name: Run Fate + run: LD_LIBRARY_PATH="$(printf "%s:" "$PWD"/lib*)$PWD" make fate fate-build SAMPLES=$PWD/fate-suite -j$(nproc) + compile_only: + name: Fate (Win64, Build-Only) + strategy: + fail-fast: false + matrix: + image: ["ghcr.io/btbn/ffmpeg-builds/win64-gpl-7.1:latest"] + runs-on: linux-amd64 + container: ${{ matrix.image }} + steps: + - name: Checkout + uses: actions/checkout@v4 + - name: Configure + run: | + ./configure --pkg-config-flags="--static" $FFBUILD_TARGET_FLAGS $FF_CONFIGURE \ + --cc="$CC" --cxx="$CXX" --ar="$AR" --ranlib="$RANLIB" --nm="$NM" \ + --extra-cflags="$FF_CFLAGS" --extra-cxxflags="$FF_CXXFLAGS" \ + --extra-libs="$FF_LIBS" --extra-ldflags="$FF_LDFLAGS" --extra-ldexeflags="$FF_LDEXEFLAGS" + - name: Build + run: make -j$(nproc) + - name: Run Fate + run: make -j$(nproc) fate-build diff --git a/COPYING.LGPLv2.1 b/COPYING.LGPLv2.1 index 58af0d378..40924c2a6 100644 --- a/COPYING.LGPLv2.1 +++ b/COPYING.LGPLv2.1 @@ -55,7 +55,7 @@ modified by someone else and passed on, the recipients should know that what they have is not the original version, so that the original author's reputation will not be affected by problems that might be introduced by others. - + Finally, software patents pose a constant threat to the existence of any free program. We wish to make sure that a company cannot effectively restrict the users of a free program by obtaining a @@ -111,7 +111,7 @@ modification follow. Pay close attention to the difference between a "work based on the library" and a "work that uses the library". The former contains code derived from the library, whereas the latter must be combined with the library in order to run. - + GNU LESSER GENERAL PUBLIC LICENSE TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION @@ -158,7 +158,7 @@ Library. You may charge a fee for the physical act of transferring a copy, and you may at your option offer warranty protection in exchange for a fee. - + 2. You may modify your copy or copies of the Library or any portion of it, thus forming a work based on the Library, and copy and distribute such modifications or work under the terms of Section 1 @@ -216,7 +216,7 @@ instead of to this License. (If a newer version than version 2 of the ordinary GNU General Public License has appeared, then you can specify that version instead if you wish.) Do not make any other change in these notices. - + Once this change is made in a given copy, it is irreversible for that copy, so the ordinary GNU General Public License applies to all subsequent copies and derivative works made from that copy. @@ -267,7 +267,7 @@ Library will still fall under Section 6.) distribute the object code for the work under the terms of Section 6. Any executables containing that work also fall under Section 6, whether or not they are linked directly with the Library itself. - + 6. As an exception to the Sections above, you may also combine or link a "work that uses the Library" with the Library to produce a work containing portions of the Library, and distribute that work @@ -329,7 +329,7 @@ restrictions of other proprietary libraries that do not normally accompany the operating system. Such a contradiction means you cannot use both them and the Library together in an executable that you distribute. - + 7. You may place library facilities that are a work based on the Library side-by-side in a single library together with other library facilities not covered by this License, and distribute such a combined @@ -370,7 +370,7 @@ subject to these terms and conditions. You may not impose any further restrictions on the recipients' exercise of the rights granted herein. You are not responsible for enforcing compliance by third parties with this License. - + 11. If, as a consequence of a court judgment or allegation of patent infringement or for any other reason (not limited to patent issues), conditions are imposed on you (whether by court order, agreement or @@ -422,7 +422,7 @@ conditions either of that version or of any later version published by the Free Software Foundation. If the Library does not specify a license version number, you may choose any version ever published by the Free Software Foundation. - + 14. If you wish to incorporate parts of the Library into other free programs whose distribution conditions are incompatible with these, write to the author to ask for permission. For software which is @@ -456,7 +456,7 @@ SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. END OF TERMS AND CONDITIONS - + How to Apply These Terms to Your New Libraries If you develop a new library, and you want it to be of the greatest diff --git a/Changelog b/Changelog index baf207172..57f020872 100644 --- a/Changelog +++ b/Changelog @@ -1,6 +1,248 @@ Entries are sorted chronologically from oldest to youngest within each release, releases are sorted from youngest to oldest. +version 7.1.4: + avcodec/dfpwmdec: Check nb_samples + avcodec/alsdec: do not set nbits invalidly + swscale/swscale_unscaled: adjust last line copy + avformat/avidec: check LIST size in avi_load_index() + avformat/avidec: validate INFO list size before parsing + avformat/matroskadec: Check audio.sub_packet_h * audio.frame_size + libavformat/xwma: fix overflow in seek position + avformat/pcm: Use 64bit for byte_rate + avcodec/hevc/ps: validate rep_format dimensions in multi-layer SPS + avfilter/vf_kerndeint: Check for minimum height + avcodec/ralf: Add the missing return statement after the error log + avfilter/vf_codecview: Clamp block to the visible frame region + avcodec/zmbv: reject XOR data that overruns the decompression buffer + avcodec/rasc: fix heap use-after-free in decode_move() + avformat/rtpdec_mpeg4: reject zero-length AU header sections + avcodec/hevc/refs: Check multiplication in alloc_frame() + fftools/ffmpeg_opt: validate stream index in negative map handling + avformat/rtmpproto: prevent integer overflow accumulating FLV buffer size + avformat/rtmpproto: validate compressed SWF header length + avformat/rtsp: Fix out-of-bounds read in SDP parser when control_url is empty + avformat/rtpdec_latm: avoid integer overflow in LATM length parsing + avcodec/h264: recompute per-slice direct mode state for every slice + avcodec/h264_refs: Clear stale pointers from ref_list + avcodec/pdvdec: Check input space before buffer allocation + avformat/concat: guard total_size overflow + avformat/iamf_parse.c: Fix potential integer overflow in opus_decoder_config() + avcodec/wmaenc: Fix missing padding in extradata + avformat: Fix various extradata padding issues + avcodec/tdsc: remove double stride adjustment + avformat/cafdec: fix negative index use in read_seek + avcodec/notchlc: Check 255 loops + avformat/rtpdec_jpeg: check qtable_len + avformat/vividas: use-of-uninitialized-value in keybuffer + avcodec/tdsc: Check jpeg size + avcodec/tdsc: Better input size check + avcodec/tdsc: Check tile_size + avcodec/decode: Better documentation for ff_set_dimensions() + avformat/mov: Limit maximum box size for mov_read_lhvc() + avformat/mov: reject dimg references with zero entries + avformat/mov: check extradata in mov_read_dops() + avformat/mov: Check read size for opus extradata + avformat/rtspdec: reject non-positive ANNOUNCE Content-Length + avformat/wavdec: Fix use-of-uninitialized-value in find_guid() + lavfi: vf_drawtext: check memory allocation + avcodec/svq1dec: Check input space for minimum + avcodec/vp9: Rollback dimensions when format is rejected + avformat/rtpdec_qdm2: Check block_size + avfilter/vf_ssim360: fix integer overflow in tape_length allocation + avcodec/escape130: Initialize old_y_avg + avutil/samplefmt: Dont claim that av_get_sample_fmt_string checks sample_fmt + avformat: check avio_read() return values in dss/dtshd/mlv + avcodec/aac/aacdec_usac: Implement missing bits of otts_bands_phase and residual_bands computation + avcodec/alsdec: preserve full float value in zero-truncated samples + avcodec/alsdec: propagate read_diff_float_data() errors in read_frame_data() + avcodec/alsdec: fix mantissa unpacking in compressed Part A path + avfilter/vf_drawtext: fix newline rendered as .notdef glyph + libavfilter/vf_v360: fix operator precedence in stereo loop condition + avcodec/alsdec: fix abs(INT_MIN) UB in read_diff_float_data() + avformat/rsd: reject short ADPCM_THP extradata reads + avformat/mov: Handle integer overflow in MOV parser + avcodec/dvdsub_parser: Fix buf_size check + avfilter/af_pan: fix sscanf() return value checks in parse_channel_name + avutil/bswap: fix implicit conversion warning in av_bswap64 + avcodec/h2645_sei: don't use provider_code uninitialized + avformat/mpegts: fix descriptor accounting across multiple IOD descriptors + avcodec/xxan: zero-initialize y_buffer + avcodec/exr: Check input space before reverse_lut() + avcodec/cbs_h266_syntax_template: Check tile_y + avcodec/h264_slice: reject slice_num >= 0xFFFF + lavfi/bwdif: fix heap-buffer-overflow with small height videos + avcodec/cbs_h266_syntax_template: Fix w/h typo + aacdec_usac: skip FD-specific decoding for LPD channels + avutil/timecode: Check for integer overflow in av_timecode_init_from_components() + avcodec/cbs_h266_syntax_template: Fix rows vs columns + avformat/mov: do not allocate out-of-range buffers + avfilter/af_lv2: call lilv_instance_activate before lilv_instance_run + avformat/rtmpproto: fix listen_timeout conversion for special negative values + avcodec/aom_film_grain: Remove impossible check + avcodec/aom_film_grain: avoid duplicate indexes in ff_aom_parse_film_grain_sets() + swscale/output: fix integer overflows in chroma in yuv2rgba64_X_c_template() + avcodec/lcldec: Fixes uqvq overflow + fftools/ffmpeg_demux: Check metadata provided filename + avcodec/av1dec: sync frame header and tile group behavior with CBS + avformat/mlvdec: avoid uninitialized read in read_string() + avcodec/magicyuv: fix small median images + swscale/output: Fix integer overflow in alpha in yuv2rgba64_1_c_template() + swscale/utils: Check *Inc + avfilter/vf_scale: Fix integer overflow in config_props() + swscale/output: Fixes integer overflow in yuv2planeX_8_c + swscale/utils: initialize chroma when luma switched to cascade + avcodec/utils: fix duration computation based on frame_bytes + avcodec/cbs_h266_syntax_template: bound slice width/height by remaining tiles + avformat/rtsp: Pass blacklist + avformat/rtsp: Explicitly check protocol + avfilter/vf_convolution: Use avpriv_mirror + avfilter/vf_convolution: Handle corner cases with small frames + avcodec/pnmdec: Check input size against width*height assuming at least 1bit per pixel + avformat/mov: Fix multiple issues related to mov_read_iref_dimg() + avcodec/snowenc: avoid NULL ptr arithmetic + avformat/mov: use 64bit in CENC subsample bounds checks + avutil/eval: Check depth of AVExpr + avformat/vividas: Reset n_audio_subpackets on error + avformat/matroskadec: Check that end_time_ns >= start_time_ns + avcodec/vp3: Sanity check cropping + avformat/dhav: Check avio_seek() return + avformat/segafilm: dont read uninitialized value + avcodec/mpegvideo_enc: Restructure ff_h263_encode_gob_header() relation to update_mb_info() + avcodec/exr: check tile_attr.x/ySize + avformat/demux: Fix integer overflows in select_from_pts_buffer() + avcodec/golomb: Fix get_ur_golomb_jpegls() with esclen = 0 + swresample/resample_template: add casts to avoid undefined overflows + avcodec/h264_parser: Check pts for overflow + avformat/rtpenc: use unsigned type for ssrc option + avformat/wtvdec: Check that language is fully read + avcodec/imm5: Dont pass EAGAIN on as is + avcodec/interplayacm: Check input for fill_block() + avcodec/hdrdec: Check input size before buffer allocation + avcodec/tmv: Move space check before buffer allocation + avcodec/flashsv: Check for input space before (re)allocating frame + avcodec/mdec: Check input space vs minimal block size + avcodec/h264_parser: Check remaining input length in loop in scan_mmco_reset() + avcodec/exr: fix AVERROR typo + avcodec/jpeg2000htdec: Check Lcup and Lref + avcodec/cfhd: Check transform type before continuing + avcodec/cfhd: Add CFHDSegment enum and named identifiers + avcodec/hevc/ps: Check bit_depth_cm in/out relation + avformat/icodec: Check size + avformat/lrcdec: Check ss for finiteness + avformat/http: Also count redirects from the cache + avformat/http: allow adjusting the redirect limit + fftools/ffmpeg_opt: limit recursion of presets + swscale/rgb2rgb_template: fix signed shift into sign bit + swresample: Check ch layouts in swr_alloc_set_opts2() + swresample: Check user chlayout in swr_set_matrix() + avcodec/bmp: fix indention + avcodec/exr: Handle axmax like bxmin in 04d7a6d3db56ea1a93908ff2d3d312e3fc40a58c + avformat/flvdec: Check *size in cts parsing + avformat/cafdec: Check nb_entries in read_info_chunk() + avcodec/vp9: Reallocate on resolution change which does not change tile_cols + avformat/img2dec: Check avio_size() for failure + avformat/mpegtsenc: Check remaining space in SDT + avformat/img2enc: Check split planes packet size + avformat/yuv4mpegen: Sanity check input packet frame dimensions + avformat/iff: Error out with 0 channel loudspeaker configuration + Fix overflow in STSD parser + avcodec/adpcm: Check input buffer size + avformat/scd: Use ffio_read_size() + avcodec/hevc/sei: Use get_bits64() in decode_nal_sei_3d_reference_displays_info() + avformat/hls: Check for integer overflow with #EXTINF: + avcodec/dca_xll: Clear padding in ff_dca_xll_parse() + vfilter/vf_find_rect: Clamp x/y min/max to valid values + avcodec/lzf: Remove size messing from ff_lzf_uncompress() + avcodec/dxv: Clear tex_data padding on reallocation + avcodec/dca_xll: Check get_rice_array() + avutil/dovi_meta: Document valid range for index of av_dovi_get_ext() + avformat/mpegts: Check program_info_length + avformat/mpegts: Check IOD_DESCRIPTOR len + avcodec/qdm2: fix heap-use-after-free in qdm2_decode_frame + avcodec/jpeg2000dec: Print bpno level when erroring out + avcodec/jpeg2000dec: allow M_b == 31 + avcodec/jpeg2000dec: Print M_b value when asking for a sample + avformat/dashdec: check value valid after read value from mpd xml + swscale/utils: zero init filter memory as before + libavfilter/showcwt: fix OOB write for DU/RL position init + lavc/j2kdec: Do not ignore colour association for packed formats + swscale/utils: Sanity check sizeFactor + swscale/utils: Avoid FF_ALLOC_TYPED_ARRAY() and use av_malloc_array() directly + avcodec/mjpegdec: fix segfault on extern_huff and no extradata + avcodec/exr: use av_realloc_array() + avcodec/omx: Check extradata size and nFilledLen + lavc/aacdec_usac: fix CPE channel index in ff_aac_usac_reset_state() + avfilter/scale_eval: Use 64bit for factor_w/h + avfilter/scale_eval: Avoid undefined behavior with double to int cast + avformat/http: Check that the protocol of redirects is http or https + doc/mailing-list-faq.texi: Fix typo in link anchor + avfilter/vf_find_rect: Fix handling odd sized images + avcodec/notchlc: zero-initialize history buffer + avfilter/vf_stack: add checks for the final canvas dimensions + lavc/vvc: Prevent OOB write to slice_top_left_ctu_x in PPS CBS + avcodec/mjpegdec: only test the size bound in sequential mjpeg + avcodec/jpeg2000htdec: Check pLSB + avformat/hls: fix double space + avformat/hls: Check seg size and offset for overflow + avcodec/jpeg2000dec: Make M_b check broader + swscale/output: Use 64bit in addition in yuv2gbrp16_full_X_c() for RGB + Y + avformat/flac_picture: Correct check + avformat/demux: ensure avformat_find_stream_info updates internal stream contexts + avfilter/vf_neighbor_opencl: add error condition when filter name doesn't match + avfilter/vf_libopencv: make sure there is space for null-terminator in shape_str + avcodec/aacdec: Fix heap-use-after-free in USAC decoding + avdevice/gdigrab: suppress int to pointer cast warning + avutil/hwcontext_d3d12va: use hwdev context for logging + fate: add missing options in config template + avformat/hls_sample_encryption: add missing padding for audio setup buffer + (fforge/pr/22824) lavc/videotoolbox_vp9: fix vpcC flags offset + lavc/videotoolboxenc: return SEI parse errors + (fforge/pr/22407) aarch64/hpeldsp_neon: fix out-of-bounds read + (fforge/pr/22406, fforge/pr/22313) avformat/mov: fix cases where we discard iamf packets from enabled streams + avformat/mov: fix setting iamf stream id offsets + (fforge/pr/21698) avcodec/tableprint_vlc: Unbreak hardcoded tables + tests: Fix fate-run.sh to handle busybox-w32 absolute paths + configure: Recognize uname "Windows_NT" as using an .exe suffix + avformat/tests/movenc: Make objects static + (fforge/pr/21626) avcodec/libsvtav1: rename aq_mode for v4.0.0 + (fforge/pr/21563) avformat/mov: add an offset to IAMF streams + (fforge/pr/21443) avfilter/vf_lcevc: attach a reference to the source frame to each passed in base picture + avfilter/vf_lcevc: support LCEVCdec version 4 + avcodec/lcevc: attach a reference to the source frame to each passed in base picture + avcodec/lcevcdec: free pictures on error + avcodec/lcevcdec: fix input dimensions for the base picture + avcodec/lcevcdec: avoid copying the input frame + avcodec/decode: Optimize lcevc away if disabled + avcodec/decode: Put lcevc fields into structure of their own + avcodec/decode: Don't allocate LCEVC context for non-video + avcodec/lcevcdec: support LCEVCdec version 4 + forgejo: backport CI job names + (fforge/pr/21337) avformat/img2dec: reject input images too big to fit into a single packet + (fforge/pr/21331) avformat/iamf_writer: check that stream count is consistent for ambisonic Audio Elements + avformat/iamf_writer: fix writting some ambisonics fields in Audio Elements + avformat/iamf_parse: fix setting denominator in AVIAMFLayer.demixing_matrix + (fforge/pr/21219) fate/ffmpeg: remove comparison against ref from fix_sub_duration_heartbeat + (fforge/pr/21146) configure: Lower libdvdnav and libdvdread minimum versions for EL9 + (fforge/pr/20943) avformat/rtsp: fix leading space in RTSP reason + avformat/rtsp: do not log invalid values + avformat/http: Handle IPv6 Zone ID in hostname + avfilter/af_amerge: fix possible crash with custom layouts + avfilter/stack_internal: fix checkheaders test + all: apply linter fixes + forgejo: apply needed CI changes for 7.1 + forgejo: backport CI to release/7.1 + (fforge/pr/21089) avcodec/vp3: Sync VLCs once during init, fix crash + configure: unbreak glslang build + avformat/iamf_parse: fix compilation error + avfilter/vf_scale: don't attempt to rescale AV_NOPTS_VALUE + avfilter/framesync: don't attempt to rescale AV_NOPTS_VALUE + avformat/iamf_parse: ensure the stream count in a scalable channel representation is equal to the audio element's stream count + avformat/iamf_parse: ensure each layout in an scalable channel representation has an increasing number of channels + fftools/ffmpeg_filter: close all no-longer needed inputs + avfilter/buffersrc: add av_buffersrc_get_status() + + version 7.1.3: avutil/common: cast GET_BYTE/GET_16BIT returned value avfilter/vf_drawtext: fix call GET_UTF8 with invalid argument diff --git a/RELEASE b/RELEASE index 1996c5044..b7f8ee41e 100644 --- a/RELEASE +++ b/RELEASE @@ -1 +1 @@ -7.1.3 +7.1.4 diff --git a/VERSION b/VERSION index 1996c5044..b7f8ee41e 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -7.1.3 +7.1.4 diff --git a/configure b/configure index 98b582a5d..1652b0d4a 100755 --- a/configure +++ b/configure @@ -4734,7 +4734,7 @@ fi exesuf() { case $1 in - mingw32*|mingw64*|msys*|win32|win64|cygwin*|*-dos|freedos|opendos|os/2*|symbian) echo .exe ;; + mingw32*|mingw64*|msys*|win32|win64|cygwin*|*-dos|freedos|opendos|os/2*|symbian|windows_nt) echo .exe ;; esac } @@ -6905,8 +6905,8 @@ enabled libdav1d && require_pkg_config libdav1d "dav1d >= 0.5.0" "dav1d enabled libdavs2 && require_pkg_config libdavs2 "davs2 >= 1.6.0" davs2.h davs2_decoder_open enabled libdc1394 && require_pkg_config libdc1394 libdc1394-2 dc1394/dc1394.h dc1394_new enabled libdrm && check_pkg_config libdrm libdrm xf86drm.h drmGetVersion -enabled libdvdnav && require_pkg_config libdvdnav "dvdnav >= 6.1.1" dvdnav/dvdnav.h dvdnav_open2 -enabled libdvdread && require_pkg_config libdvdread "dvdread >= 6.1.2" dvdread/dvd_reader.h DVDOpen2 +enabled libdvdnav && require_pkg_config libdvdnav "dvdnav >= 6.1.0" dvdnav/dvdnav.h dvdnav_open2 +enabled libdvdread && require_pkg_config libdvdread "dvdread >= 6.1.1" dvdread/dvd_reader.h DVDOpen2 enabled libfdk_aac && { check_pkg_config libfdk_aac fdk-aac "fdk-aac/aacenc_lib.h" aacEncOpen || { require libfdk_aac fdk-aac/aacenc_lib.h aacEncOpen -lfdk-aac && warn "using libfdk without pkg-config"; } } @@ -6917,12 +6917,16 @@ enabled libfontconfig && require_pkg_config libfontconfig fontconfig "fontco enabled libfreetype && require_pkg_config libfreetype freetype2 "ft2build.h FT_FREETYPE_H" FT_Init_FreeType enabled libfribidi && require_pkg_config libfribidi fribidi fribidi.h fribidi_version_info enabled libharfbuzz && require_pkg_config libharfbuzz harfbuzz hb.h hb_buffer_create -enabled libglslang && { check_lib spirv_compiler glslang/Include/glslang_c_interface.h glslang_initialize_process \ +if enabled libglslang; then + spvremap="-lSPVRemapper" + require_headers "glslang/build_info.h" && { test_cpp_condition glslang/build_info.h "GLSLANG_VERSION_MAJOR >= 16" && spvremap="" ; } + check_lib spirv_compiler glslang/Include/glslang_c_interface.h glslang_initialize_process \ -lglslang -lMachineIndependent -lGenericCodeGen \ - -lSPVRemapper -lSPIRV -lSPIRV-Tools-opt -lSPIRV-Tools -lpthread -lstdc++ -lm || + ${spvremap} -lSPIRV -lSPIRV-Tools-opt -lSPIRV-Tools -lpthread -lstdc++ -lm || require spirv_compiler glslang/Include/glslang_c_interface.h glslang_initialize_process \ -lglslang -lMachineIndependent -lOSDependent -lHLSL -lOGLCompiler -lGenericCodeGen \ - -lSPVRemapper -lSPIRV -lSPIRV-Tools-opt -lSPIRV-Tools -lpthread -lstdc++ -lm ; } + ${spvremap} -lSPIRV -lSPIRV-Tools-opt -lSPIRV-Tools -lpthread -lstdc++ -lm ; +fi enabled libgme && { check_pkg_config libgme libgme gme/gme.h gme_new_emu || require libgme gme/gme.h gme_new_emu -lgme -lstdc++; } enabled libgsm && { for gsm_hdr in "gsm.h" "gsm/gsm.h"; do @@ -8213,7 +8217,7 @@ cat > $TMPH < make -k Continue build in case of errors, this is useful for the regression tests sometimes but note that it will still not run all reg tests. - diff --git a/doc/fate_config.sh.template b/doc/fate_config.sh.template index 4ff8629d4..6400d9dbe 100644 --- a/doc/fate_config.sh.template +++ b/doc/fate_config.sh.template @@ -11,16 +11,21 @@ ignore_tests= # the following are optional and map to configure options arch= cpu= +toolchain= cross_prefix= as= cc= +cxx= ld= +nm= target_os= sysroot= target_exec= target_path= target_samples= extra_cflags= +extra_cxxflags= +extra_objcflags= extra_ldflags= extra_libs= extra_conf= # extra configure options not covered above diff --git a/doc/infra.txt b/doc/infra.txt index 79d4e5671..37aaef34b 100644 --- a/doc/infra.txt +++ b/doc/infra.txt @@ -96,4 +96,3 @@ IRC: ~~~~ irc channels are at https://libera.chat/ irc channel archives are at https://libera.irclog.whitequark.org - diff --git a/doc/mailing-list-faq.texi b/doc/mailing-list-faq.texi index e10d92a5f..49328de7a 100644 --- a/doc/mailing-list-faq.texi +++ b/doc/mailing-list-faq.texi @@ -341,7 +341,7 @@ recommended. Avoid sending the same message to multiple mailing lists. @item -Please follow our @url{https://ffmpeg.org/community.html#Code-of-conduct, Code of Conduct}. +Please follow our @url{https://ffmpeg.org/community.html#Code-of-Conduct, Code of Conduct}. @end itemize @chapter Help diff --git a/doc/nut.texi b/doc/nut.texi index f9b18f566..d3a5b8de3 100644 --- a/doc/nut.texi +++ b/doc/nut.texi @@ -157,4 +157,3 @@ PFD[32] would for example be signed 32 bit little-endian IEEE float @item XVID @tab non-compliant MPEG-4 generated by old Xvid @item XVIX @tab non-compliant MPEG-4 generated by old Xvid with interlacing bug @end multitable - diff --git a/doc/texi2pod.pl b/doc/texi2pod.pl old mode 100644 new mode 100755 diff --git a/doc/texidep.pl b/doc/texidep.pl old mode 100644 new mode 100755 diff --git a/doc/undefined.txt b/doc/undefined.txt index e01299bef..faf8816c6 100644 --- a/doc/undefined.txt +++ b/doc/undefined.txt @@ -44,4 +44,3 @@ a+b*c; here the reader knows that a,b,c are meant to be signed integers but for C standard compliance / to avoid undefined behavior they are stored in unsigned ints. - diff --git a/fftools/ffmpeg.h b/fftools/ffmpeg.h index 733d551fa..83ccc4134 100644 --- a/fftools/ffmpeg.h +++ b/fftools/ffmpeg.h @@ -254,6 +254,8 @@ typedef struct OptionsContext { SpecifierOptList enc_stats_pre_fmt; SpecifierOptList enc_stats_post_fmt; SpecifierOptList mux_stats_fmt; + + int depth; } OptionsContext; enum IFilterFlags { diff --git a/fftools/ffmpeg_demux.c b/fftools/ffmpeg_demux.c index 7d87422ee..cd12d84d2 100644 --- a/fftools/ffmpeg_demux.c +++ b/fftools/ffmpeg_demux.c @@ -1560,6 +1560,56 @@ static int ist_add(const OptionsContext *o, Demuxer *d, AVStream *st, AVDictiona return 0; } +static int is_windows_reserved_device_name(const char *f) +{ +#if HAVE_DOS_PATHS + for (const char *p = f; p && *p; ) { + char stem[6], *s; + av_strlcpy(stem, p, sizeof(stem)); + if ((s = strchr(stem, '.'))) + *s = 0; + if ((s = strpbrk(stem, "123456789"))) + *s = '1'; + + if( !av_strcasecmp(stem, "AUX") || + !av_strcasecmp(stem, "CON") || + !av_strcasecmp(stem, "NUL") || + !av_strcasecmp(stem, "PRN") || + !av_strcasecmp(stem, "COM1") || + !av_strcasecmp(stem, "LPT1") + ) + return 1; + + p = strchr(p, '/'); + if (p) + p++; + } +#endif + return 0; +} + +static int safe_filename(const char *f, int allow_subdir) +{ + const char *start = f; + + if (!*f || is_windows_reserved_device_name(f)) + return 0; + + for (; *f; f++) { + /* A-Za-z0-9_- */ + if (!((unsigned)((*f | 32) - 'a') < 26 || + (unsigned)(*f - '0') < 10 || *f == '_' || *f == '-')) { + if (f == start) + return 0; + else if (allow_subdir && *f == '/') + start = f + 1; + else if (*f != '.') + return 0; + } + } + return 1; +} + static int dump_attachment(InputStream *ist, const char *filename) { AVStream *st = ist->st; @@ -1571,8 +1621,13 @@ static int dump_attachment(InputStream *ist, const char *filename) av_log(ist, AV_LOG_WARNING, "No extradata to dump.\n"); return 0; } - if (!*filename && (e = av_dict_get(st->metadata, "filename", NULL, 0))) + if (!*filename && (e = av_dict_get(st->metadata, "filename", NULL, 0))) { filename = e->value; + if (!safe_filename(filename, 0)) { + av_log(ist, AV_LOG_ERROR, "Filename %s is unsafe\n", filename); + return AVERROR(EINVAL); + } + } if (!*filename) { av_log(ist, AV_LOG_FATAL, "No filename specified and no 'filename' tag"); return AVERROR(EINVAL); diff --git a/fftools/ffmpeg_filter.c b/fftools/ffmpeg_filter.c index 3ef6818c7..4eec8fed7 100644 --- a/fftools/ffmpeg_filter.c +++ b/fftools/ffmpeg_filter.c @@ -2365,6 +2365,18 @@ finish: fps->dropped_keyframe |= fps->last_dropped && (frame->flags & AV_FRAME_FLAG_KEY); } +static void close_input(FilterGraph *fg, int input_idx) +{ + + InputFilterPriv *ifp = ifp_from_ifilter(fg->inputs[input_idx]); + FilterGraphPriv *fgp = fgp_from_fg(ifp->ifilter.graph); + + if (!ifp->eof) { + sch_filter_receive_finish(fgp->sch, fgp->sch_idx, input_idx); + ifp->eof = 1; + } +} + static int close_output(OutputFilterPriv *ofp, FilterGraphThread *fgt) { FilterGraphPriv *fgp = fgp_from_fg(ofp->ofilter.graph); @@ -3035,7 +3047,7 @@ static int filter_thread(void *arg) if (ret == AVERROR_EOF) { av_log(fg, AV_LOG_VERBOSE, "Input %u no longer accepts new data\n", input_idx); - sch_filter_receive_finish(fgp->sch, fgp->sch_idx, input_idx); + close_input(fg, input_idx); continue; } if (ret < 0) @@ -3052,6 +3064,13 @@ read_frames: av_err2str(ret)); goto finish; } + + // ensure all inputs no longer accepting data are closed + for (int i = 0; fgt.graph && i < fg->nb_inputs; i++) { + InputFilterPriv *ifp = ifp_from_ifilter(fg->inputs[i]); + if (av_buffersrc_get_status(ifp->filter)) + close_input(fg, i); + } } for (unsigned i = 0; i < fg->nb_outputs; i++) { diff --git a/fftools/ffmpeg_opt.c b/fftools/ffmpeg_opt.c index f639a1cf0..71e7f1467 100644 --- a/fftools/ffmpeg_opt.c +++ b/fftools/ffmpeg_opt.c @@ -545,6 +545,8 @@ static int opt_map(void *optctx, const char *opt, const char *arg) for (i = 0; i < o->nb_stream_maps; i++) { m = &o->stream_maps[i]; if (file_idx == m->file_index && + m->stream_index >= 0 && + m->stream_index < input_files[m->file_index]->nb_streams && stream_specifier_match(&ss, input_files[m->file_index]->ctx, input_files[m->file_index]->ctx->streams[m->stream_index], @@ -1008,6 +1010,12 @@ static int opt_preset(void *optctx, const char *opt, const char *arg) char filename[1000], line[1000], tmp_line[1000]; const char *codec_name = NULL; int ret = 0; + int depth = o->depth; + + if (depth > 2) { + av_log(NULL, AV_LOG_ERROR, "too deep recursion\n"); + return AVERROR(EINVAL); + } codec_name = opt_match_per_type_str(&o->codec_names, *opt); @@ -1019,6 +1027,7 @@ static int opt_preset(void *optctx, const char *opt, const char *arg) return AVERROR(ENOENT); } + o->depth ++; while (fgets(line, sizeof(line), f)) { char *key = tmp_line, *value, *endptr; @@ -1046,6 +1055,7 @@ static int opt_preset(void *optctx, const char *opt, const char *arg) } fail: + o->depth = depth; fclose(f); return ret; diff --git a/libavcodec/Makefile b/libavcodec/Makefile index 153a9e388..9d1c1fc30 100644 --- a/libavcodec/Makefile +++ b/libavcodec/Makefile @@ -46,7 +46,6 @@ OBJS = ac3_parser.o \ get_buffer.o \ imgconvert.o \ jni.o \ - lcevcdec.o \ mathtables.o \ mediacodec.o \ mpeg12framerate.o \ @@ -124,6 +123,7 @@ OBJS-$(CONFIG_IVIDSP) += ivi_dsp.o OBJS-$(CONFIG_JNI) += ffjni.o jni.o OBJS-$(CONFIG_JPEGTABLES) += jpegtables.o OBJS-$(CONFIG_LCMS2) += fflcms2.o +OBJS-$(CONFIG_LIBLCEVC_DEC) += lcevcdec.o OBJS-$(CONFIG_LLAUDDSP) += lossless_audiodsp.o OBJS-$(CONFIG_LLVIDDSP) += lossless_videodsp.o OBJS-$(CONFIG_LLVIDENCDSP) += lossless_videoencdsp.o diff --git a/libavcodec/aac/aacdec.c b/libavcodec/aac/aacdec.c index 325e52834..add73d9b1 100644 --- a/libavcodec/aac/aacdec.c +++ b/libavcodec/aac/aacdec.c @@ -164,6 +164,12 @@ static av_cold int che_configure(AACDecContext *ac, } } else { if (ac->che[type][id]) { + for (int i = 0; i < FF_ARRAY_ELEMS(ac->tag_che_map); i++) { + for (int j = 0; j < MAX_ELEM_ID; j++) { + if (ac->tag_che_map[i][j] == ac->che[type][id]) + ac->tag_che_map[i][j] = NULL; + } + } ac->proc.sbr_ctx_close(ac->che[type][id]); } av_freep(&ac->che[type][id]); diff --git a/libavcodec/aac/aacdec_usac.c b/libavcodec/aac/aacdec_usac.c index 661252304..ac68e54ae 100644 --- a/libavcodec/aac/aacdec_usac.c +++ b/libavcodec/aac/aacdec_usac.c @@ -213,18 +213,33 @@ static int decode_usac_element_pair(AACDecContext *ac, if (e->stereo_config_index) { e->mps.freq_res = get_bits(gb, 3); /* bsFreqRes */ + if (!e->mps.freq_res) + return AVERROR_INVALIDDATA; /* value 0 is reserved */ + int numBands = ((int[]){0,28,20,14,10,7,5,4})[e->mps.freq_res]; // ISO/IEC 23003-1:2007, 5.2, Table 39 + e->mps.fixed_gain = get_bits(gb, 3); /* bsFixedGainDMX */ e->mps.temp_shape_config = get_bits(gb, 2); /* bsTempShapeConfig */ e->mps.decorr_config = get_bits(gb, 2); /* bsDecorrConfig */ e->mps.high_rate_mode = get_bits1(gb); /* bsHighRateMode */ e->mps.phase_coding = get_bits1(gb); /* bsPhaseCoding */ - if (get_bits1(gb)) /* bsOttBandsPhasePresent */ - e->mps.otts_bands_phase = get_bits(gb, 5); /* bsOttBandsPhase */ + int otts_bands_phase = ((int[]){0,10,10,7,5,3,2,2})[e->mps.freq_res]; // Table 109 — Default value of bsOttBandsPhase + if (get_bits1(gb)) { /* bsOttBandsPhasePresent */ + otts_bands_phase = get_bits(gb, 5); /* bsOttBandsPhase */ + if (otts_bands_phase > numBands) + return AVERROR_INVALIDDATA; + } + e->mps.otts_bands_phase = otts_bands_phase; e->mps.residual_coding = e->stereo_config_index >= 2; /* bsResidualCoding */ if (e->mps.residual_coding) { - e->mps.residual_bands = get_bits(gb, 5); /* bsResidualBands */ + int residual_bands = get_bits(gb, 5); /* bsResidualBands */ + if (residual_bands > numBands) + return AVERROR_INVALIDDATA; + e->mps.residual_bands = residual_bands; + + e->mps.otts_bands_phase = FFMAX(e->mps.otts_bands_phase, + e->mps.residual_bands); e->mps.pseudo_lr = get_bits1(gb); /* bsPseudoLr */ } if (e->mps.temp_shape_config == 2) @@ -315,7 +330,7 @@ int ff_aac_usac_reset_state(AACDecContext *ac, OutputConfiguration *oc) ff_aac_sbr_config_usac(ac, che, e); for (int j = 0; j < ch; j++) { - SingleChannelElement *sce = &che->ch[ch]; + SingleChannelElement *sce = &che->ch[j]; AACUsacElemData *ue = &sce->ue; memset(ue, 0, sizeof(*ue)); @@ -1288,7 +1303,8 @@ static void spectrum_decode(AACDecContext *ac, AACUSACConfig *usac, SingleChannelElement *sce = &cpe->ch[ch]; AACUsacElemData *ue = &sce->ue; - spectrum_scale(ac, sce, ue); + if (!ue->core_mode) + spectrum_scale(ac, sce, ue); } if (nb_channels > 1 && us->common_window) { @@ -1338,8 +1354,9 @@ static void spectrum_decode(AACDecContext *ac, AACUSACConfig *usac, if (sce->tns.present && ((nb_channels == 1) || (us->tns_on_lr))) ac->dsp.apply_tns(sce->coeffs, &sce->tns, &sce->ics, 1); - ac->oc[1].m4ac.frame_length_short ? ac->dsp.imdct_and_windowing_768(ac, sce) : - ac->dsp.imdct_and_windowing(ac, sce); + if (!sce->ue.core_mode) + ac->oc[1].m4ac.frame_length_short ? ac->dsp.imdct_and_windowing_768(ac, sce) : + ac->dsp.imdct_and_windowing(ac, sce); } } diff --git a/libavcodec/aarch64/hpeldsp_neon.S b/libavcodec/aarch64/hpeldsp_neon.S index e7c1549c4..fd2c2c98c 100644 --- a/libavcodec/aarch64/hpeldsp_neon.S +++ b/libavcodec/aarch64/hpeldsp_neon.S @@ -50,12 +50,13 @@ .endm .macro pixels16_x2 rnd=1, avg=0 -1: ld1 {v0.16b, v1.16b}, [x1], x2 - ld1 {v2.16b, v3.16b}, [x1], x2 +1: + ldur q1, [x1, #1] + ld1 {v0.16b}, [x1], x2 subs w3, w3, #2 - ext v1.16b, v0.16b, v1.16b, #1 + ldur q3, [x1, #1] + ld1 {v2.16b}, [x1], x2 avg v0.16b, v0.16b, v1.16b - ext v3.16b, v2.16b, v3.16b, #1 avg v2.16b, v2.16b, v3.16b .if \avg ld1 {v1.16b}, [x0], x2 @@ -108,20 +109,20 @@ .macro pixels16_xy2 rnd=1, avg=0 sub w3, w3, #2 - ld1 {v0.16b, v1.16b}, [x1], x2 - ld1 {v4.16b, v5.16b}, [x1], x2 + ldur q1, [x1, #1] + ld1 {v0.16b}, [x1], x2 NRND movi v26.8H, #1 - ext v1.16b, v0.16b, v1.16b, #1 - ext v5.16b, v4.16b, v5.16b, #1 + ldur q5, [x1, #1] + ld1 {v4.16b}, [x1], x2 uaddl v16.8h, v0.8b, v1.8b uaddl2 v20.8h, v0.16b, v1.16b uaddl v18.8h, v4.8b, v5.8b uaddl2 v22.8h, v4.16b, v5.16b 1: subs w3, w3, #2 - ld1 {v0.16b, v1.16b}, [x1], x2 + ldur q30, [x1, #1] + ld1 {v0.16b}, [x1], x2 add v24.8h, v16.8h, v18.8h NRND add v24.8H, v24.8H, v26.8H - ext v30.16b, v0.16b, v1.16b, #1 add v1.8h, v20.8h, v22.8h mshrn v28.8b, v24.8h, #2 NRND add v1.8H, v1.8H, v26.8H @@ -131,12 +132,12 @@ NRND add v1.8H, v1.8H, v26.8H urhadd v28.16b, v28.16b, v16.16b .endif uaddl v16.8h, v0.8b, v30.8b - ld1 {v2.16b, v3.16b}, [x1], x2 + ldur q3, [x1, #1] + ld1 {v2.16b}, [x1], x2 uaddl2 v20.8h, v0.16b, v30.16b st1 {v28.16b}, [x0], x2 add v24.8h, v16.8h, v18.8h NRND add v24.8H, v24.8H, v26.8H - ext v3.16b, v2.16b, v3.16b, #1 add v0.8h, v20.8h, v22.8h mshrn v30.8b, v24.8h, #2 NRND add v0.8H, v0.8H, v26.8H @@ -150,10 +151,10 @@ NRND add v0.8H, v0.8H, v26.8H st1 {v30.16b}, [x0], x2 b.gt 1b - ld1 {v0.16b, v1.16b}, [x1], x2 + ldur q30, [x1, #1] + ld1 {v0.16b}, [x1], x2 add v24.8h, v16.8h, v18.8h NRND add v24.8H, v24.8H, v26.8H - ext v30.16b, v0.16b, v1.16b, #1 add v1.8h, v20.8h, v22.8h mshrn v28.8b, v24.8h, #2 NRND add v1.8H, v1.8H, v26.8H @@ -206,10 +207,11 @@ NRND add v0.8H, v0.8H, v26.8H .endm .macro pixels8_x2 rnd=1, avg=0 -1: ld1 {v0.8b, v1.8b}, [x1], x2 - ext v1.8b, v0.8b, v1.8b, #1 - ld1 {v2.8b, v3.8b}, [x1], x2 - ext v3.8b, v2.8b, v3.8b, #1 +1: + ldur d1, [x1, #1] + ld1 {v0.8b}, [x1], x2 + ldur d3, [x1, #1] + ld1 {v2.8b}, [x1], x2 subs w3, w3, #2 avg v0.8b, v0.8b, v1.8b avg v2.8b, v2.8b, v3.8b @@ -263,22 +265,23 @@ NRND add v0.8H, v0.8H, v26.8H .endm .macro pixels8_xy2 rnd=1, avg=0 + ldur d4, [x1, #1] sub w3, w3, #2 - ld1 {v0.16b}, [x1], x2 - ld1 {v1.16b}, [x1], x2 + ld1 {v0.8b}, [x1], x2 NRND movi v19.8H, #1 - ext v4.16b, v0.16b, v4.16b, #1 - ext v6.16b, v1.16b, v6.16b, #1 + ldur d6, [x1, #1] + ld1 {v1.8b}, [x1], x2 uaddl v16.8h, v0.8b, v4.8b uaddl v17.8h, v1.8b, v6.8b 1: subs w3, w3, #2 - ld1 {v0.16b}, [x1], x2 + ldur d4, [x1, #1] + ld1 {v0.8b}, [x1], x2 add v18.8h, v16.8h, v17.8h - ext v4.16b, v0.16b, v4.16b, #1 NRND add v18.8H, v18.8H, v19.8H uaddl v16.8h, v0.8b, v4.8b mshrn v5.8b, v18.8h, #2 - ld1 {v1.16b}, [x1], x2 + ldur d6, [x1, #1] + ld1 {v1.8b}, [x1], x2 add v18.8h, v16.8h, v17.8h .if \avg ld1 {v7.8b}, [x0] @@ -291,14 +294,13 @@ NRND add v18.8H, v18.8H, v19.8H ld1 {v5.8b}, [x0] urhadd v7.8b, v7.8b, v5.8b .endif - ext v6.16b, v1.16b, v6.16b, #1 uaddl v17.8h, v1.8b, v6.8b st1 {v7.8b}, [x0], x2 b.gt 1b - ld1 {v0.16b}, [x1], x2 + ldur d4, [x1, #1] + ld1 {v0.8b}, [x1], x2 add v18.8h, v16.8h, v17.8h - ext v4.16b, v0.16b, v4.16b, #1 NRND add v18.8H, v18.8H, v19.8H uaddl v16.8h, v0.8b, v4.8b mshrn v5.8b, v18.8h, #2 diff --git a/libavcodec/adpcm.c b/libavcodec/adpcm.c index c6b6e22e9..a07e7d779 100644 --- a/libavcodec/adpcm.c +++ b/libavcodec/adpcm.c @@ -857,6 +857,8 @@ static int get_nb_samples(AVCodecContext *avctx, GetByteContext *gb, if(ch <= 0) return 0; + if (buf_size > INT_MAX / 2) + return 0; switch (avctx->codec->id) { /* constant, only check buf_size */ diff --git a/libavcodec/alsdec.c b/libavcodec/alsdec.c index 26eba6d2e..aff393a48 100644 --- a/libavcodec/alsdec.c +++ b/libavcodec/alsdec.c @@ -1540,8 +1540,12 @@ static int read_diff_float_data(ALSDecContext *ctx, unsigned int ra_frame) { return AVERROR_INVALIDDATA; } + j = 0; for (i = 0; i < frame_length; ++i) { - ctx->raw_mantissa[c][i] = AV_RB32(larray); + if (ctx->raw_samples[c][i] == 0) { + ctx->raw_mantissa[c][i] = AV_RB32(larray + j); + j += 4; + } } } } @@ -1552,7 +1556,10 @@ static int read_diff_float_data(ALSDecContext *ctx, unsigned int ra_frame) { if (ctx->raw_samples[c][i] != 0) { //The following logic is taken from Tabel 14.45 and 14.46 from the ISO spec if (av_cmp_sf_ieee754(acf[c], FLOAT_1)) { - nbits[i] = 23 - av_log2(abs(ctx->raw_samples[c][i])); + int nbit = av_log2(FFABSU(ctx->raw_samples[c][i])); + if (nbit > 23) + return AVERROR_INVALIDDATA; + nbits[i] = 23 - nbit; } else { nbits[i] = 23; } @@ -1626,7 +1633,7 @@ static int read_diff_float_data(ALSDecContext *ctx, unsigned int ra_frame) { tmp_32 = (sign << 31) | ((e + EXP_BIAS) << 23) | (mantissa); ctx->raw_samples[c][i] = tmp_32; } else { - ctx->raw_samples[c][i] = raw_mantissa[c][i] & 0x007fffffUL; + ctx->raw_samples[c][i] = raw_mantissa[c][i]; } } align_get_bits(gb); @@ -1782,7 +1789,9 @@ static int read_frame_data(ALSDecContext *ctx, unsigned int ra_frame) } if (sconf->floating) { - read_diff_float_data(ctx, ra_frame); + ret = read_diff_float_data(ctx, ra_frame); + if (ret < 0) + return ret; } if (get_bits_left(gb) < 0) { diff --git a/libavcodec/aom_film_grain.c b/libavcodec/aom_film_grain.c index 1b1693dcd..440e69331 100644 --- a/libavcodec/aom_film_grain.c +++ b/libavcodec/aom_film_grain.c @@ -152,8 +152,9 @@ int ff_aom_parse_film_grain_sets(AVFilmGrainAFGS1Params *s, payload_4byte = get_bits1(gb); payload_size = get_bits(gb, payload_4byte ? 2 : 8); set_idx = get_bits(gb, 3); + fgp = av_film_grain_params_alloc(&fgp_size); - if (!fgp) + if (!fgp || s->sets[set_idx]) goto error; aom = &fgp->codec.aom; @@ -212,7 +213,7 @@ int ff_aom_parse_film_grain_sets(AVFilmGrainAFGS1Params *s, } predict_scaling = get_bits1(gb); - if (predict_scaling && (!ref || ref == fgp)) + if (predict_scaling && !ref) goto error; // prediction must be from valid, different set predict_y_scaling = predict_scaling ? get_bits1(gb) : 0; diff --git a/libavcodec/arm/int_neon.S b/libavcodec/arm/int_neon.S index 72c4c77c4..3c58b7284 100644 --- a/libavcodec/arm/int_neon.S +++ b/libavcodec/arm/int_neon.S @@ -48,4 +48,3 @@ function ff_scalarproduct_int16_neon, export=1 vmov.32 r0, d3[0] bx lr endfunc - diff --git a/libavcodec/av1dec.c b/libavcodec/av1dec.c index 1d5b9ef4f..d921def59 100644 --- a/libavcodec/av1dec.c +++ b/libavcodec/av1dec.c @@ -98,12 +98,11 @@ static int32_t decode_signed_subexp_with_ref(uint32_t sub_exp, int low, static void read_global_param(AV1DecContext *s, int type, int ref, int idx) { - uint8_t primary_frame, prev_frame; + int primary_frame; uint32_t abs_bits, prec_bits, round, prec_diff, sub, mx; int32_t r, prev_gm_param; primary_frame = s->raw_frame_header->primary_ref_frame; - prev_frame = s->raw_frame_header->ref_frame_idx[primary_frame]; abs_bits = AV1_GM_ABS_ALPHA_BITS; prec_bits = AV1_GM_ALPHA_PREC_BITS; @@ -113,8 +112,10 @@ static void read_global_param(AV1DecContext *s, int type, int ref, int idx) */ if (s->raw_frame_header->primary_ref_frame == AV1_PRIMARY_REF_NONE) prev_gm_param = s->cur_frame.gm_params[ref][idx]; - else + else { + int prev_frame = s->raw_frame_header->ref_frame_idx[primary_frame]; prev_gm_param = s->ref[prev_frame].gm_params[ref][idx]; + } if (idx < 2) { if (type == AV1_WARP_MODEL_TRANSLATION) { @@ -1300,6 +1301,8 @@ static int av1_receive_frame_internal(AVCodecContext *avctx, AVFrame *frame) ff_refstruct_replace(&s->seq_ref, unit->content_ref); s->raw_seq = &obu->obu.sequence_header; + s->raw_frame_header = NULL; + raw_tile_group = NULL; ret = set_context_with_sequence(avctx, s->raw_seq); if (ret < 0) { @@ -1327,6 +1330,8 @@ static int av1_receive_frame_internal(AVCodecContext *avctx, AVFrame *frame) ff_refstruct_replace(&s->header_ref, unit->content_ref); + raw_tile_group = NULL; + if (unit->type == AV1_OBU_FRAME) s->raw_frame_header = &obu->obu.frame.header; else @@ -1398,8 +1403,11 @@ static int av1_receive_frame_internal(AVCodecContext *avctx, AVFrame *frame) } } break; - case AV1_OBU_TILE_LIST: case AV1_OBU_TEMPORAL_DELIMITER: + s->raw_frame_header = NULL; + raw_tile_group = NULL; + // fall-through + case AV1_OBU_TILE_LIST: case AV1_OBU_PADDING: break; case AV1_OBU_METADATA: diff --git a/libavcodec/bmp.c b/libavcodec/bmp.c index 360c10320..9e9f62d91 100644 --- a/libavcodec/bmp.c +++ b/libavcodec/bmp.c @@ -129,7 +129,7 @@ static int bmp_decode_frame(AVCodecContext *avctx, AVFrame *p, rgb[1] = bytestream_get_le32(&buf); rgb[2] = bytestream_get_le32(&buf); if (ihsize > 40) - alpha = bytestream_get_le32(&buf); + alpha = bytestream_get_le32(&buf); } ret = ff_set_dimensions(avctx, width, height > 0 ? height : -(unsigned)height); diff --git a/libavcodec/cbs_h266_syntax_template.c b/libavcodec/cbs_h266_syntax_template.c index 19a4b3d71..851f2734a 100644 --- a/libavcodec/cbs_h266_syntax_template.c +++ b/libavcodec/cbs_h266_syntax_template.c @@ -1218,7 +1218,7 @@ static int FUNC(sps)(CodedBitstreamContext *ctx, RWContext *rw, int num_subpic_cols = tmp_width_val / (current->sps_subpic_width_minus1[0] + 1); if (tmp_width_val % (current->sps_subpic_width_minus1[0] + 1) || - tmp_height_val % (current->sps_subpic_width_minus1[0] + 1) || + tmp_height_val % (current->sps_subpic_height_minus1[0] + 1) || current->sps_num_subpics_minus1 != (num_subpic_cols * tmp_height_val / (current->sps_subpic_height_minus1[0] + 1) - 1)) @@ -1972,16 +1972,18 @@ static int FUNC(pps) (CodedBitstreamContext *ctx, RWContext *rw, for (i = 0; i < current->pps_num_slices_in_pic_minus1; i++) { tile_x = tile_idx % current->num_tile_columns; tile_y = tile_idx / current->num_tile_columns; + if (tile_y >= current->num_tile_rows) + return AVERROR_INVALIDDATA; if (tile_x != current->num_tile_columns - 1) { ues(pps_slice_width_in_tiles_minus1[i], - 0, current->num_tile_columns - 1, 1, i); + 0, current->num_tile_columns - 1 - tile_x, 1, i); } else { infer(pps_slice_width_in_tiles_minus1[i], 0); } if (tile_y != current->num_tile_rows - 1 && (current->pps_tile_idx_delta_present_flag || tile_x == 0)) { ues(pps_slice_height_in_tiles_minus1[i], - 0, current->num_tile_rows - 1, 1, i); + 0, current->num_tile_rows - 1 - tile_y, 1, i); } else { if (tile_y == current->num_tile_rows - 1) infer(pps_slice_height_in_tiles_minus1[i], 0); @@ -2013,6 +2015,12 @@ static int FUNC(pps) (CodedBitstreamContext *ctx, RWContext *rw, slice_top_left_ctu_y[i] = ctu_y; } else { uint16_t slice_height_in_ctus; + int num_uniform_slices; + + if (i + current->pps_num_exp_slices_in_tile[i] > + current->pps_num_slices_in_pic_minus1 + 1) + return AVERROR_INVALIDDATA; + for (j = 0; j < current->pps_num_exp_slices_in_tile[i]; j++) { ues(pps_exp_slice_height_in_ctus_minus1[i][j], 0, @@ -2033,6 +2041,13 @@ static int FUNC(pps) (CodedBitstreamContext *ctx, RWContext *rw, uniform_slice_height = 1 + (j == 0 ? current->row_height_val[tile_y] - 1: current->pps_exp_slice_height_in_ctus_minus1[i][j-1]); + + num_uniform_slices = (remaining_height_in_ctbs_y + uniform_slice_height - 1) + / uniform_slice_height; + if (i + current->pps_num_exp_slices_in_tile[i] + num_uniform_slices > + current->pps_num_slices_in_pic_minus1 + 1) + return AVERROR_INVALIDDATA; + while (remaining_height_in_ctbs_y > uniform_slice_height) { current->slice_height_in_ctus[i + j] = uniform_slice_height; @@ -3441,7 +3456,7 @@ static int FUNC(slice_header) (CodedBitstreamContext *ctx, RWContext *rw, tile_idx <= current->sh_slice_address + current->sh_num_tiles_in_slice_minus1; tile_idx++) { - tile_y = tile_idx / pps->num_tile_rows; + tile_y = tile_idx / pps->num_tile_columns; height = pps->row_height_val[tile_y]; current->num_entry_points += (entropy_sync ? height : 1); } diff --git a/libavcodec/cfhd.c b/libavcodec/cfhd.c index 7d8aca371..30a25c9c7 100644 --- a/libavcodec/cfhd.c +++ b/libavcodec/cfhd.c @@ -639,7 +639,7 @@ static int cfhd_decode(AVCodecContext *avctx, AVFrame *pic, } else av_log(avctx, AV_LOG_DEBUG, "Unknown tag %i data %x\n", tag, data); - if (tag == BitstreamMarker && data == 0xf0f && + if (tag == BitstreamMarker && data == CoefficientSegment && s->coded_format != AV_PIX_FMT_NONE) { int lowpass_height = s->plane[s->channel_num].band[0][0].height; int lowpass_width = s->plane[s->channel_num].band[0][0].width; @@ -706,10 +706,15 @@ static int cfhd_decode(AVCodecContext *avctx, AVFrame *pic, if (s->subband_num_actual == 255) goto finish; + + if (tag == BitstreamMarker && data == CoefficientSegment || tag == BandHeader || tag == BandSecondPass || s->peak.level) + if (s->transform_type != s->a_transform_type) + return AVERROR_PATCHWELCOME; + coeff_data = s->plane[s->channel_num].subband[s->subband_num_actual]; /* Lowpass coefficients */ - if (tag == BitstreamMarker && data == 0xf0f) { + if (tag == BitstreamMarker && data == CoefficientSegment) { int lowpass_height, lowpass_width, lowpass_a_height, lowpass_a_width; if (!s->a_width || !s->a_height) { diff --git a/libavcodec/cfhd.h b/libavcodec/cfhd.h index 9b09c9126..445a0362b 100644 --- a/libavcodec/cfhd.h +++ b/libavcodec/cfhd.h @@ -92,6 +92,15 @@ enum CFHDParam { ChannelHeight = 105, }; +enum CFHDSegment { + LowPassSegment = 0x1a4a, + LowPassEndSegment = 0x1b4b, + HighPassSegment = 0x0d0d, + BandSegment = 0x0e0e, + HighPassEndSegment = 0x0c0c, + CoefficientSegment = 0x0f0f, +}; + #define VLC_BITS 9 #define SUBBAND_COUNT 10 #define SUBBAND_COUNT_3D 17 diff --git a/libavcodec/cfhdenc.c b/libavcodec/cfhdenc.c index ceea15efc..b3bd8edb5 100644 --- a/libavcodec/cfhdenc.c +++ b/libavcodec/cfhdenc.c @@ -627,7 +627,7 @@ static int cfhd_encode_frame(AVCodecContext *avctx, AVPacket *pkt, } bytestream2_put_be16(pby, BitstreamMarker); - bytestream2_put_be16(pby, 0x1a4a); + bytestream2_put_be16(pby, LowPassSegment); pos = bytestream2_tell_p(pby); @@ -653,7 +653,7 @@ static int cfhd_encode_frame(AVCodecContext *avctx, AVPacket *pkt, bytestream2_put_be16(pby, 16); bytestream2_put_be16(pby, BitstreamMarker); - bytestream2_put_be16(pby, 0x0f0f); + bytestream2_put_be16(pby, CoefficientSegment); for (int i = 0; i < height; i++) { for (int j = 0; j < width; j++) @@ -662,7 +662,7 @@ static int cfhd_encode_frame(AVCodecContext *avctx, AVPacket *pkt, } bytestream2_put_be16(pby, BitstreamMarker); - bytestream2_put_be16(pby, 0x1b4b); + bytestream2_put_be16(pby, LowPassEndSegment); for (int l = 0; l < 3; l++) { for (int i = 0; i < 3; i++) { @@ -677,7 +677,7 @@ static int cfhd_encode_frame(AVCodecContext *avctx, AVPacket *pkt, int height = s->plane[p].band[l][0].height; bytestream2_put_be16(pby, BitstreamMarker); - bytestream2_put_be16(pby, 0x0d0d); + bytestream2_put_be16(pby, HighPassSegment); bytestream2_put_be16(pby, WaveletType); bytestream2_put_be16(pby, 3 + 2 * (l == 2)); @@ -714,7 +714,7 @@ static int cfhd_encode_frame(AVCodecContext *avctx, AVPacket *pkt, int count = 0, padd = 0; bytestream2_put_be16(pby, BitstreamMarker); - bytestream2_put_be16(pby, 0x0e0e); + bytestream2_put_be16(pby, BandSegment); bytestream2_put_be16(pby, SubbandNumber); bytestream2_put_be16(pby, i + 1); @@ -783,7 +783,7 @@ static int cfhd_encode_frame(AVCodecContext *avctx, AVPacket *pkt, } bytestream2_put_be16(pby, BitstreamMarker); - bytestream2_put_be16(pby, 0x0c0c); + bytestream2_put_be16(pby, HighPassEndSegment); } s->plane[p].size = bytestream2_tell_p(pby) - pos; diff --git a/libavcodec/cljrdec.c b/libavcodec/cljrdec.c index 66e9d56e0..79fbea990 100644 --- a/libavcodec/cljrdec.c +++ b/libavcodec/cljrdec.c @@ -88,4 +88,3 @@ const FFCodec ff_cljr_decoder = { FF_CODEC_DECODE_CB(decode_frame), .p.capabilities = AV_CODEC_CAP_DR1, }; - diff --git a/libavcodec/dca_xll.c b/libavcodec/dca_xll.c index 005a51ed6..cecaee202 100644 --- a/libavcodec/dca_xll.c +++ b/libavcodec/dca_xll.c @@ -64,12 +64,16 @@ static void get_linear_array(GetBitContext *gb, int32_t *array, int size, int n) array[i] = get_linear(gb, n); } -static void get_rice_array(GetBitContext *gb, int32_t *array, int size, int k) +static int get_rice_array(GetBitContext *gb, int32_t *array, int size, int k) { int i; - for (i = 0; i < size; i++) + for (i = 0; i < size && get_bits_left(gb) > k; i++) array[i] = get_rice(gb, k); + + if (i < size) + return AVERROR_INVALIDDATA; + return 0; } static int parse_dmix_coeffs(DCAXllDecoder *s, DCAXllChSet *c) @@ -529,8 +533,10 @@ static int chs_parse_band_data(DCAXllDecoder *s, DCAXllChSet *c, int band, int s } else { // Rice codes // Unpack all residuals of part A of segment 0 - get_rice_array(&s->gb, part_a, c->nsamples_part_a[k], - c->bitalloc_part_a[k]); + int ret = get_rice_array(&s->gb, part_a, c->nsamples_part_a[k], + c->bitalloc_part_a[k]); + if (ret < 0) + return ret; if (c->bitalloc_hybrid_linear[k]) { // Hybrid Rice codes @@ -560,7 +566,9 @@ static int chs_parse_band_data(DCAXllDecoder *s, DCAXllChSet *c, int band, int s } else { // Rice codes // Unpack all residuals of part B of segment 0 and others - get_rice_array(&s->gb, part_b, nsamples_part_b, c->bitalloc_part_b[k]); + ret = get_rice_array(&s->gb, part_b, nsamples_part_b, c->bitalloc_part_b[k]); + if (ret < 0) + return ret; } } } @@ -1094,6 +1102,7 @@ static int copy_to_pbr(DCAXllDecoder *s, const uint8_t *data, int size, int dela return AVERROR(ENOMEM); memcpy(s->pbr_buffer, data, size); + memset(s->pbr_buffer + size, 0, AV_INPUT_BUFFER_PADDING_SIZE); s->pbr_length = size; s->pbr_delay = delay; return 0; @@ -1148,6 +1157,7 @@ static int parse_frame_pbr(DCAXllDecoder *s, const uint8_t *data, int size, DCAE memcpy(s->pbr_buffer + s->pbr_length, data, size); s->pbr_length += size; + memset(s->pbr_buffer + s->pbr_length, 0, AV_INPUT_BUFFER_PADDING_SIZE); // Respect decoding delay after synchronization error if (s->pbr_delay > 0 && --s->pbr_delay) diff --git a/libavcodec/decode.c b/libavcodec/decode.c index d8d3bd4d1..0ab0f4bb4 100644 --- a/libavcodec/decode.c +++ b/libavcodec/decode.c @@ -92,10 +92,14 @@ typedef struct DecodeContext { */ uint64_t side_data_pref_mask; - FFLCEVCContext *lcevc; - int lcevc_frame; - int width; - int height; +#if CONFIG_LIBLCEVC_DEC + struct { + FFLCEVCContext *ctx; + int frame; + int width; + int height; + } lcevc; +#endif } DecodeContext; static DecodeContext *decode_ctx(AVCodecInternal *avci) @@ -1657,26 +1661,29 @@ int ff_attach_decode_data(AVFrame *frame) static void update_frame_props(AVCodecContext *avctx, AVFrame *frame) { +#if CONFIG_LIBLCEVC_DEC AVCodecInternal *avci = avctx->internal; DecodeContext *dc = decode_ctx(avci); - dc->lcevc_frame = dc->lcevc && avctx->codec_type == AVMEDIA_TYPE_VIDEO && + dc->lcevc.frame = dc->lcevc.ctx && avctx->codec_type == AVMEDIA_TYPE_VIDEO && av_frame_get_side_data(frame, AV_FRAME_DATA_LCEVC); - if (dc->lcevc_frame) { - dc->width = frame->width; - dc->height = frame->height; + if (dc->lcevc.frame) { + dc->lcevc.width = frame->width; + dc->lcevc.height = frame->height; frame->width = frame->width * 2 / FFMAX(frame->sample_aspect_ratio.den, 1); frame->height = frame->height * 2 / FFMAX(frame->sample_aspect_ratio.num, 1); } +#endif } static int attach_post_process_data(AVCodecContext *avctx, AVFrame *frame) { +#if CONFIG_LIBLCEVC_DEC AVCodecInternal *avci = avctx->internal; DecodeContext *dc = decode_ctx(avci); - if (dc->lcevc_frame) { + if (dc->lcevc.frame) { FrameDecodeData *fdd = (FrameDecodeData*)frame->private_ref->data; FFLCEVCFrame *frame_ctx; int ret; @@ -1691,13 +1698,13 @@ static int attach_post_process_data(AVCodecContext *avctx, AVFrame *frame) return AVERROR(ENOMEM); } - frame_ctx->lcevc = ff_refstruct_ref(dc->lcevc); + frame_ctx->lcevc = ff_refstruct_ref(dc->lcevc.ctx); frame_ctx->frame->width = frame->width; frame_ctx->frame->height = frame->height; frame_ctx->frame->format = frame->format; - frame->width = dc->width; - frame->height = dc->height; + frame->width = dc->lcevc.width; + frame->height = dc->lcevc.height; ret = avctx->get_buffer2(avctx, frame_ctx->frame, 0); if (ret < 0) { @@ -1711,7 +1718,8 @@ static int attach_post_process_data(AVCodecContext *avctx, AVFrame *frame) fdd->post_process_opaque_free = ff_lcevc_unref; fdd->post_process = ff_lcevc_process; } - dc->lcevc_frame = 0; + dc->lcevc.frame = 0; +#endif return 0; } @@ -2084,9 +2092,13 @@ int ff_decode_preinit(AVCodecContext *avctx) return ret; if (!(avctx->export_side_data & AV_CODEC_EXPORT_DATA_ENHANCEMENTS)) { - ret = ff_lcevc_alloc(&dc->lcevc); - if (ret < 0 && (avctx->err_recognition & AV_EF_EXPLODE)) - return ret; + if (avctx->codec_type == AVMEDIA_TYPE_VIDEO) { +#if CONFIG_LIBLCEVC_DEC + ret = ff_lcevc_alloc(&dc->lcevc.ctx); + if (ret < 0 && (avctx->err_recognition & AV_EF_EXPLODE)) + return ret; +#endif + } } #if FF_API_DROPCHANGED @@ -2331,13 +2343,17 @@ void ff_decode_internal_sync(AVCodecContext *dst, const AVCodecContext *src) dst_dc->initial_pict_type = src_dc->initial_pict_type; dst_dc->intra_only_flag = src_dc->intra_only_flag; - ff_refstruct_replace(&dst_dc->lcevc, src_dc->lcevc); +#if CONFIG_LIBLCEVC_DEC + ff_refstruct_replace(&dst_dc->lcevc.ctx, src_dc->lcevc.ctx); +#endif } void ff_decode_internal_uninit(AVCodecContext *avctx) { +#if CONFIG_LIBLCEVC_DEC AVCodecInternal *avci = avctx->internal; DecodeContext *dc = decode_ctx(avci); - ff_refstruct_unref(&dc->lcevc); + ff_refstruct_unref(&dc->lcevc.ctx); +#endif } diff --git a/libavcodec/decode.h b/libavcodec/decode.h index 2c3719a8d..6cafb48cd 100644 --- a/libavcodec/decode.h +++ b/libavcodec/decode.h @@ -93,9 +93,13 @@ int ff_attach_decode_data(AVFrame *frame); */ int ff_copy_palette(void *dst, const AVPacket *src, void *logctx); -/** - * Check that the provided frame dimensions are valid and set them on the codec - * context. +/* + * Validate and set video frame dimensions on AVCodecContext. + * + * Dimensions accepted here satisfy FFmpeg's generic image-size validation + * (see av_image_check_size2()). Decoder code normally should not duplicate + * generic width/height overflow checks before ff_get_buffer(); add local + * checks only for codec-specific derived sizes or complexity bounds. */ int ff_set_dimensions(AVCodecContext *s, int width, int height); diff --git a/libavcodec/dfpwmdec.c b/libavcodec/dfpwmdec.c index 4ddb80656..6a7a23e39 100644 --- a/libavcodec/dfpwmdec.c +++ b/libavcodec/dfpwmdec.c @@ -101,15 +101,16 @@ static int dfpwm_dec_frame(struct AVCodecContext *ctx, AVFrame *frame, { DFPWMState *state = ctx->priv_data; int ret; + uint64_t nb_samples = packet->size * 8LL / ctx->ch_layout.nb_channels; if (packet->size * 8LL % ctx->ch_layout.nb_channels) return AVERROR_PATCHWELCOME; - frame->nb_samples = packet->size * 8LL / ctx->ch_layout.nb_channels; - if (frame->nb_samples <= 0) { + if (nb_samples > INT_MAX || !nb_samples) { av_log(ctx, AV_LOG_ERROR, "invalid number of samples in packet\n"); return AVERROR_INVALIDDATA; } + frame->nb_samples = nb_samples; if ((ret = ff_get_buffer(ctx, frame, 0)) < 0) return ret; diff --git a/libavcodec/dv_profile.c b/libavcodec/dv_profile.c index f40311418..02ece47e0 100644 --- a/libavcodec/dv_profile.c +++ b/libavcodec/dv_profile.c @@ -337,4 +337,3 @@ const AVDVProfile *av_dv_codec_profile2(int width, int height, return p; } - diff --git a/libavcodec/dvdsub_parser.c b/libavcodec/dvdsub_parser.c index 8871b6a38..400bdb8b9 100644 --- a/libavcodec/dvdsub_parser.c +++ b/libavcodec/dvdsub_parser.c @@ -59,7 +59,7 @@ static int dvdsub_parse(AVCodecParserContext *s, pc->packet = av_malloc(pc->packet_len + AV_INPUT_BUFFER_PADDING_SIZE); } if (pc->packet) { - if (pc->packet_index + buf_size <= pc->packet_len) { + if (buf_size <= pc->packet_len - pc->packet_index) { memcpy(pc->packet + pc->packet_index, buf, buf_size); pc->packet_index += buf_size; if (pc->packet_index >= pc->packet_len) { diff --git a/libavcodec/dxv.c b/libavcodec/dxv.c index 70497b7d9..b043709af 100644 --- a/libavcodec/dxv.c +++ b/libavcodec/dxv.c @@ -828,7 +828,12 @@ static int dxv_decompress_dxt5(AVCodecContext *avctx) static int dxv_decompress_lzf(AVCodecContext *avctx) { DXVContext *ctx = avctx->priv_data; - return ff_lzf_uncompress(&ctx->gbc, &ctx->tex_data, &ctx->tex_size, &ctx->tex_data_size); + unsigned old_size = ctx->tex_data_size; + int ret = ff_lzf_uncompress(&ctx->gbc, &ctx->tex_data, &ctx->tex_size, &ctx->tex_data_size); + old_size = FFMAX(old_size, ctx->tex_size); + if (ctx->tex_data_size > old_size) + memset(ctx->tex_data + old_size, 0, ctx->tex_data_size - old_size); + return ret; } static int dxv_decompress_raw(AVCodecContext *avctx) diff --git a/libavcodec/escape130.c b/libavcodec/escape130.c index 3b0460fd7..9b2c6204f 100644 --- a/libavcodec/escape130.c +++ b/libavcodec/escape130.c @@ -125,7 +125,7 @@ static av_cold int escape130_decode_init(AVCodecContext *avctx) return AVERROR_INVALIDDATA; } - s->old_y_avg = av_malloc(avctx->width * avctx->height / 4); + s->old_y_avg = av_mallocz(avctx->width * avctx->height / 4); s->buf1 = av_malloc(avctx->width * avctx->height * 3 / 2); s->buf2 = av_malloc(avctx->width * avctx->height * 3 / 2); if (!s->old_y_avg || !s->buf1 || !s->buf2) { diff --git a/libavcodec/exr.c b/libavcodec/exr.c index c9d22435f..2b47ab50a 100644 --- a/libavcodec/exr.c +++ b/libavcodec/exr.c @@ -632,6 +632,9 @@ static int piz_uncompress(const EXRContext *s, const uint8_t *src, int ssize, max_non_zero - min_non_zero + 1); memset(td->bitmap + max_non_zero + 1, 0, BITMAP_SIZE - max_non_zero - 1); + if (bytestream2_get_bytes_left(&gb) < 4) + return AVERROR_INVALIDDATA; + maxval = reverse_lut(td->bitmap, td->lut); bytestream2_skip(&gb, 4); @@ -1458,7 +1461,8 @@ static int decode_block(AVCodecContext *avctx, void *tdata, } // Zero out the end if xmax+1 is not w - memset(ptr_x, 0, axmax); + if (s->desc->flags & AV_PIX_FMT_FLAG_PLANAR || !c) + memset(ptr_x, 0, axmax); channel_buffer[c] += td->channel_line_size; } } @@ -1780,12 +1784,17 @@ static int decode_header(EXRContext *s, AVFrame *frame) } } - s->channels = av_realloc(s->channels, - ++s->nb_channels * sizeof(EXRChannel)); - if (!s->channels) { + av_assert0(s->nb_channels < INT_MAX); // Impossible due to size of the bitstream + EXRChannel *new_channels = av_realloc_array(s->channels, + s->nb_channels + 1, + sizeof(EXRChannel)); + if (!new_channels) { ret = AVERROR(ENOMEM); goto fail; } + s->nb_channels ++; + s->channels = new_channels; + channel = &s->channels[s->nb_channels - 1]; channel->pixel_type = current_pixel_type; channel->xsub = xsub; @@ -1808,7 +1817,7 @@ static int decode_header(EXRContext *s, AVFrame *frame) s->is_luma = 1; } else { avpriv_request_sample(s->avctx, "Uncommon channel combination"); - ret = AVERROR(AVERROR_PATCHWELCOME); + ret = AVERROR_PATCHWELCOME; goto fail; } @@ -2207,6 +2216,8 @@ static int decode_frame(AVCodecContext *avctx, AVFrame *picture, } if (s->is_tile) { + if (s->tile_attr.ySize <= 0 || s->tile_attr.xSize <= 0) + return AVERROR_INVALIDDATA; nb_blocks = ((s->xdelta + s->tile_attr.xSize - 1) / s->tile_attr.xSize) * ((s->ydelta + s->tile_attr.ySize - 1) / s->tile_attr.ySize); } else { /* scanline */ diff --git a/libavcodec/ffv1_template.c b/libavcodec/ffv1_template.c index abb90a12e..005a32c29 100644 --- a/libavcodec/ffv1_template.c +++ b/libavcodec/ffv1_template.c @@ -50,4 +50,3 @@ static inline int RENAME(get_context)(const int16_t quant_table[MAX_CONTEXT_INPU quant_table[1][(LT - T) & MAX_QUANT_TABLE_MASK] + quant_table[2][(T - RT) & MAX_QUANT_TABLE_MASK]; } - diff --git a/libavcodec/ffv1enc_template.c b/libavcodec/ffv1enc_template.c index bc14926ab..a60490f65 100644 --- a/libavcodec/ffv1enc_template.c +++ b/libavcodec/ffv1enc_template.c @@ -208,4 +208,3 @@ static int RENAME(encode_rgb_frame)(FFV1Context *f, FFV1SliceContext *sc, } return 0; } - diff --git a/libavcodec/flashsv.c b/libavcodec/flashsv.c index d27918c92..ba5c99500 100644 --- a/libavcodec/flashsv.c +++ b/libavcodec/flashsv.c @@ -314,6 +314,9 @@ static int flashsv_decode_frame(AVCodecContext *avctx, AVFrame *rframe, v_blocks = s->image_height / s->block_height; v_part = s->image_height % s->block_height; + if (h_blocks * v_blocks * 16 > get_bits_left(&gb)) + return AVERROR_INVALIDDATA; + /* the block size could change between frames, make sure the buffer * is large enough, if not, get a larger one */ if (s->block_size < s->block_width * s->block_height) { diff --git a/libavcodec/golomb.h b/libavcodec/golomb.h index 742334978..5169a5a4c 100644 --- a/libavcodec/golomb.h +++ b/libavcodec/golomb.h @@ -455,7 +455,7 @@ static inline int get_ur_golomb_jpegls(GetBitContext *gb, int k, int limit, buf = get_bits_long(gb, k); return buf + (i << k); - } else if (i == limit - 1) { + } else if (esc_len && i == limit - 1) { buf = get_bits_long(gb, esc_len); return buf + 1; @@ -512,7 +512,7 @@ static inline int get_ur_golomb_jpegls(GetBitContext *gb, int k, int limit, } buf += ((SUINT)i << k); - } else if (i == limit - 1) { + } else if (esc_len && i == limit - 1) { buf = SHOW_UBITS(re, gb, esc_len); LAST_SKIP_BITS(re, gb, esc_len); diff --git a/libavcodec/h2645_sei.c b/libavcodec/h2645_sei.c index 62369dd37..9ff8fb8a3 100644 --- a/libavcodec/h2645_sei.c +++ b/libavcodec/h2645_sei.c @@ -144,7 +144,7 @@ static int decode_registered_user_data_closed_caption(H2645SEIA53Caption *h, static int decode_registered_user_data(H2645SEI *h, GetByteContext *gb, enum AVCodecID codec_id, void *logctx) { - int country_code, provider_code; + int country_code, provider_code = -1; if (bytestream2_get_bytes_left(gb) < 3) return AVERROR_INVALIDDATA; diff --git a/libavcodec/h264_direct.c b/libavcodec/h264_direct.c index 587274aa6..09e38ccc8 100644 --- a/libavcodec/h264_direct.c +++ b/libavcodec/h264_direct.c @@ -121,26 +121,30 @@ void ff_h264_direct_ref_list_init(const H264Context *const h, H264SliceContext * { H264Ref *const ref1 = &sl->ref_list[1][0]; H264Picture *const cur = h->cur_pic_ptr; - int list, j, field; + int list, field; int sidx = (h->picture_structure & 1) ^ 1; int ref1sidx = (ref1->reference & 1) ^ 1; - for (list = 0; list < sl->list_count; list++) { - cur->ref_count[sidx][list] = sl->ref_count[list]; - for (j = 0; j < sl->ref_count[list]; j++) - cur->ref_poc[sidx][list][j] = 4 * sl->ref_list[list][j].parent->frame_num + - (sl->ref_list[list][j].reference & 3); - } + /* Updates to cur_pic are not safe once ff_thread_finish_setup() has been + * called (other threads may already be reading these fields). */ + if (!h->setup_finished) { + for (list = 0; list < sl->list_count; list++) { + cur->ref_count[sidx][list] = sl->ref_count[list]; + for (int j = 0; j < sl->ref_count[list]; j++) + cur->ref_poc[sidx][list][j] = 4 * sl->ref_list[list][j].parent->frame_num + + (sl->ref_list[list][j].reference & 3); + } - if (h->picture_structure == PICT_FRAME) { - memcpy(cur->ref_count[1], cur->ref_count[0], sizeof(cur->ref_count[0])); - memcpy(cur->ref_poc[1], cur->ref_poc[0], sizeof(cur->ref_poc[0])); - } + if (h->picture_structure == PICT_FRAME) { + memcpy(cur->ref_count[1], cur->ref_count[0], sizeof(cur->ref_count[0])); + memcpy(cur->ref_poc[1], cur->ref_poc[0], sizeof(cur->ref_poc[0])); + } - if (h->current_slice == 0) { - cur->mbaff = FRAME_MBAFF(h); - } else { - av_assert0(cur->mbaff == FRAME_MBAFF(h)); + if (h->current_slice == 0) { + cur->mbaff = FRAME_MBAFF(h); + } else { + av_assert0(cur->mbaff == FRAME_MBAFF(h)); + } } sl->col_fieldoff = 0; diff --git a/libavcodec/h264_mc_template.c b/libavcodec/h264_mc_template.c index d02e2bf58..d24b0a0ed 100644 --- a/libavcodec/h264_mc_template.c +++ b/libavcodec/h264_mc_template.c @@ -162,4 +162,3 @@ static void MCFUNC(hl_motion)(const H264Context *h, H264SliceContext *sl, if (USES_LIST(mb_type, 1)) prefetch_motion(h, sl, 1, PIXEL_SHIFT, CHROMA_IDC); } - diff --git a/libavcodec/h264_parser.c b/libavcodec/h264_parser.c index 94cfbc481..450456185 100644 --- a/libavcodec/h264_parser.c +++ b/libavcodec/h264_parser.c @@ -223,6 +223,9 @@ static int scan_mmco_reset(AVCodecParserContext *s, GetBitContext *gb, if (get_bits1(gb)) { // adaptive_ref_pic_marking_mode_flag int i; for (i = 0; i < H264_MAX_MMCO_COUNT; i++) { + if (get_bits_left(gb) < 1) + return AVERROR_INVALIDDATA; + MMCOOpcode opcode = get_ue_golomb_31(gb); if (opcode > (unsigned) MMCO_LONG) { av_log(logctx, AV_LOG_ERROR, @@ -647,8 +650,12 @@ static int h264_parse(AVCodecParserContext *s, s->dts = av_sat_add64(p->reference_dts, av_rescale(s->dts_ref_dts_delta, num, den)); } - if (p->reference_dts != AV_NOPTS_VALUE && s->pts == AV_NOPTS_VALUE) - s->pts = s->dts + av_rescale(s->pts_dts_delta, num, den); + if (p->reference_dts != AV_NOPTS_VALUE && s->pts == AV_NOPTS_VALUE) { + int64_t pts_dts_delta = av_rescale(s->pts_dts_delta, num, den); + uint64_t pts = (uint64_t)s->dts + pts_dts_delta; + if (pts == av_sat_add64(s->dts, pts_dts_delta)) + s->pts = pts; + } if (s->dts_sync_point > 0) p->reference_dts = s->dts; // new reference diff --git a/libavcodec/h264_refs.c b/libavcodec/h264_refs.c index 5eb285506..c7dc429ae 100644 --- a/libavcodec/h264_refs.c +++ b/libavcodec/h264_refs.c @@ -156,8 +156,7 @@ static void h264_initialise_ref_list(H264Context *h, H264SliceContext *sl) h->long_ref, 16, 1, h->picture_structure); av_assert0(len <= 32); - if (len < sl->ref_count[list]) - memset(&sl->ref_list[list][len], 0, sizeof(H264Ref) * (sl->ref_count[list] - len)); + memset(&sl->ref_list[list][len], 0, sizeof(H264Ref) * (32 - len)); lens[list] = len; } @@ -178,8 +177,7 @@ static void h264_initialise_ref_list(H264Context *h, H264SliceContext *sl) h-> long_ref, 16, 1, h->picture_structure); av_assert0(len <= 32); - if (len < sl->ref_count[0]) - memset(&sl->ref_list[0][len], 0, sizeof(H264Ref) * (sl->ref_count[0] - len)); + memset(&sl->ref_list[0][len], 0, sizeof(H264Ref) * (32 - len)); } #ifdef TRACE for (int i = 0; i < sl->ref_count[0]; i++) { diff --git a/libavcodec/h264_slice.c b/libavcodec/h264_slice.c index 01c43a652..bbccd1fc4 100644 --- a/libavcodec/h264_slice.c +++ b/libavcodec/h264_slice.c @@ -1948,8 +1948,7 @@ static int h264_slice_init(H264Context *h, H264SliceContext *sl, if (sl->slice_type_nos == AV_PICTURE_TYPE_B && !sl->direct_spatial_mv_pred) ff_h264_direct_dist_scale_factor(h, sl); - if (!h->setup_finished) - ff_h264_direct_ref_list_init(h, sl); + ff_h264_direct_ref_list_init(h, sl); if (h->avctx->skip_loop_filter >= AVDISCARD_ALL || (h->avctx->skip_loop_filter >= AVDISCARD_NONKEY && @@ -1978,6 +1977,12 @@ static int h264_slice_init(H264Context *h, H264SliceContext *sl, h->ps.pps->chroma_qp_index_offset[1]) + 6 * (h->ps.sps->bit_depth_luma - 8); + // slice_table is uint16_t initialized to 0xFFFF as a sentinel. + if (h->current_slice >= 0xFFFE) { + av_log(h->avctx, AV_LOG_ERROR, "Too many slices (%d)\n", h->current_slice + 1); + return AVERROR_PATCHWELCOME; + } + sl->slice_num = ++h->current_slice; if (sl->slice_num) diff --git a/libavcodec/hdrdec.c b/libavcodec/hdrdec.c index b7ade48e3..cffa7570d 100644 --- a/libavcodec/hdrdec.c +++ b/libavcodec/hdrdec.c @@ -126,6 +126,9 @@ static int hdr_decode_frame(AVCodecContext *avctx, AVFrame *p, ; } + if (bytestream2_get_bytes_left(&gb) < height * 4) + return AVERROR_INVALIDDATA; + if ((ret = ff_set_dimensions(avctx, width, height)) < 0) return ret; diff --git a/libavcodec/hevc/cabac.c b/libavcodec/hevc/cabac.c index 892dd1c21..55d5741f8 100644 --- a/libavcodec/hevc/cabac.c +++ b/libavcodec/hevc/cabac.c @@ -1512,4 +1512,3 @@ void ff_hevc_hls_mvd_coding(HEVCLocalContext *lc, int x0, int y0, int log2_cb_si case 0: lc->pu.mvd.y = 0; break; } } - diff --git a/libavcodec/hevc/ps.c b/libavcodec/hevc/ps.c index 8b48cba8e..87d922579 100644 --- a/libavcodec/hevc/ps.c +++ b/libavcodec/hevc/ps.c @@ -1215,6 +1215,9 @@ int ff_hevc_parse_sps(HEVCSPS *sps, GetBitContext *gb, unsigned int *sps_id, sps->bit_depth = rf->bit_depth_luma; sps->width = rf->pic_width_in_luma_samples; sps->height = rf->pic_height_in_luma_samples; + if ((ret = av_image_check_size(sps->width, + sps->height, 0, avctx)) < 0) + return ret; sps->pic_conf_win.left_offset = rf->conf_win_left_offset; sps->pic_conf_win.right_offset = rf->conf_win_right_offset; @@ -1761,6 +1764,10 @@ static int colour_mapping_table(GetBitContext *gb, AVCodecContext *avctx, HEVCPP pps->luma_bit_depth_cm_output = get_ue_golomb(gb) + 8; pps->chroma_bit_depth_cm_output = get_ue_golomb(gb) + 8; + if ( pps-> luma_bit_depth_cm_output < pps-> luma_bit_depth_cm_input + || pps->chroma_bit_depth_cm_output < pps->chroma_bit_depth_cm_input) + return AVERROR_INVALIDDATA; + pps->cm_res_quant_bits = get_bits(gb, 2); pps->cm_delta_flc_bits = get_bits(gb, 2) + 1; diff --git a/libavcodec/hevc/refs.c b/libavcodec/hevc/refs.c index 6ba667e9f..19bd8886d 100644 --- a/libavcodec/hevc/refs.c +++ b/libavcodec/hevc/refs.c @@ -135,7 +135,10 @@ static HEVCFrame *alloc_frame(HEVCContext *s, HEVCLayerContext *l) if (ret < 0) return NULL; - frame->rpl = ff_refstruct_allocz(s->pkt.nb_nals * sizeof(*frame->rpl)); + size_t rpl_bytes; + if (av_size_mult(s->pkt.nb_nals, sizeof(*frame->rpl), &rpl_bytes) < 0) + goto fail; + frame->rpl = ff_refstruct_allocz(rpl_bytes); if (!frame->rpl) goto fail; frame->nb_rpl_elems = s->pkt.nb_nals; diff --git a/libavcodec/hevc/sei.c b/libavcodec/hevc/sei.c index 1af6ca271..462ce37de 100644 --- a/libavcodec/hevc/sei.c +++ b/libavcodec/hevc/sei.c @@ -180,7 +180,7 @@ static int decode_nal_sei_3d_reference_displays_info(HEVCSEITDRDI *s, GetBitCont else length = FFMAX(0, (int)s->exponent_ref_display_width[i] + (int)s->prec_ref_display_width - 31); - s->mantissa_ref_display_width[i] = get_bits_long(gb, length); + s->mantissa_ref_display_width[i] = get_bits64(gb, length); if (s->ref_viewing_distance_flag) { s->exponent_ref_viewing_distance[i] = get_bits(gb, 6); if (s->exponent_ref_viewing_distance[i] > 62) @@ -190,7 +190,7 @@ static int decode_nal_sei_3d_reference_displays_info(HEVCSEITDRDI *s, GetBitCont else length = FFMAX(0, (int)s->exponent_ref_viewing_distance[i] + (int)s->prec_ref_viewing_dist - 31); - s->mantissa_ref_viewing_distance[i] = get_bits_long(gb, length); + s->mantissa_ref_viewing_distance[i] = get_bits64(gb, length); } s->additional_shift_present_flag[i] = get_bits1(gb); if (s->additional_shift_present_flag[i]) { diff --git a/libavcodec/hevc/sei.h b/libavcodec/hevc/sei.h index 806540fac..5239ec93a 100644 --- a/libavcodec/hevc/sei.h +++ b/libavcodec/hevc/sei.h @@ -87,9 +87,9 @@ typedef struct HEVCSEITDRDI { uint16_t left_view_id[32]; uint16_t right_view_id[32]; uint8_t exponent_ref_display_width[32]; - uint8_t mantissa_ref_display_width[32]; + uint64_t mantissa_ref_display_width[32]; uint8_t exponent_ref_viewing_distance[32]; - uint8_t mantissa_ref_viewing_distance[32]; + uint64_t mantissa_ref_viewing_distance[32]; uint8_t additional_shift_present_flag[32]; int16_t num_sample_shift[32]; uint8_t three_dimensional_reference_displays_extension_flag; diff --git a/libavcodec/imgconvert.c b/libavcodec/imgconvert.c index 96511ac7d..86cfce1e4 100644 --- a/libavcodec/imgconvert.c +++ b/libavcodec/imgconvert.c @@ -45,4 +45,3 @@ enum AVPixelFormat avcodec_find_best_pix_fmt_of_list(const enum AVPixelFormat *p *loss_ptr = loss; return best; } - diff --git a/libavcodec/imm5.c b/libavcodec/imm5.c index 2535e7726..793428893 100644 --- a/libavcodec/imm5.c +++ b/libavcodec/imm5.c @@ -139,6 +139,8 @@ static int imm5_decode_frame(AVCodecContext *avctx, AVFrame *frame, } ret = avcodec_receive_frame(codec_avctx, frame); + if (ret == AVERROR(EAGAIN)) + return avpkt->size; if (ret < 0) return ret; diff --git a/libavcodec/interplayacm.c b/libavcodec/interplayacm.c index 2ae992a71..f39ce36a1 100644 --- a/libavcodec/interplayacm.c +++ b/libavcodec/interplayacm.c @@ -437,6 +437,9 @@ static int fill_block(InterplayACMContext *s) unsigned i, ind; int ret; + if (get_bits_left(gb) < s->cols * 5) + return AVERROR_INVALIDDATA; + for (i = 0; i < s->cols; i++) { ind = get_bits(gb, 5); ret = filler_list[ind](s, ind, i); diff --git a/libavcodec/jpeg2000dec.c b/libavcodec/jpeg2000dec.c index 6a86375e0..5a25079da 100644 --- a/libavcodec/jpeg2000dec.c +++ b/libavcodec/jpeg2000dec.c @@ -2038,7 +2038,7 @@ static int decode_cblk(const Jpeg2000DecoderContext *s, Jpeg2000CodingStyle *cod while (passno--) { if (bpno < 0 || bpno > 29) { - av_log(s->avctx, AV_LOG_ERROR, "bpno became invalid\n"); + av_log(s->avctx, AV_LOG_ERROR, "bpno (%d) became invalid\n", bpno); return AVERROR_INVALIDDATA; } switch(pass_t) { @@ -2237,8 +2237,8 @@ static inline int tile_codeblocks(const Jpeg2000DecoderContext *s, Jpeg2000Tile band->coord[1][0] == band->coord[1][1]) continue; - if ((codsty->cblk_style & JPEG2000_CTSY_HTJ2K_F) && M_b >= 31) { - avpriv_request_sample(s->avctx, "JPEG2000_CTSY_HTJ2K_F and M_b >= 31"); + if (M_b > 31) { + avpriv_request_sample(s->avctx, "M_b (%d) > 31", M_b); return AVERROR_PATCHWELCOME; } @@ -2317,9 +2317,12 @@ static inline int tile_codeblocks(const Jpeg2000DecoderContext *s, Jpeg2000Tile int h = tile->comp[compno].coord[1][1] - \ ff_jpeg2000_ceildiv(s->image_offset_y, s->cdy[compno]); \ int plane = 0; \ + ptrdiff_t dstoffset = 0; \ \ if (planar) \ plane = s->cdef[compno] ? s->cdef[compno]-1 : (s->ncomponents-1); \ + else \ + dstoffset = s->cdef[compno] ? s->cdef[compno] - 1 : compno; \ \ y = tile->comp[compno].coord[1][0] - \ ff_jpeg2000_ceildiv(s->image_offset_y, s->cdy[compno]); \ @@ -2329,7 +2332,7 @@ static inline int tile_codeblocks(const Jpeg2000DecoderContext *s, Jpeg2000Tile \ x = tile->comp[compno].coord[0][0] - \ ff_jpeg2000_ceildiv(s->image_offset_x, s->cdx[compno]); \ - dst = line + x * pixelsize + compno*!planar; \ + dst = line + x * pixelsize + dstoffset; \ \ if (codsty->transform == FF_DWT97) { \ for (; x < w; x++) { \ diff --git a/libavcodec/jpeg2000htdec.c b/libavcodec/jpeg2000htdec.c index c47c8d61f..8cedc4146 100644 --- a/libavcodec/jpeg2000htdec.c +++ b/libavcodec/jpeg2000htdec.c @@ -1219,7 +1219,7 @@ ff_jpeg2000_decode_htj2k(const Jpeg2000DecoderContext *s, Jpeg2000CodingStyle *c uint8_t *block_states = NULL; int32_t n, val; // Post-processing - const uint32_t mask = UINT32_MAX >> (M_b + 1); // bit mask for ROI detection + const uint32_t mask = (UINT32_MAX >> M_b) >> 1; // bit mask for ROI detection uint8_t num_rempass; @@ -1254,6 +1254,11 @@ ff_jpeg2000_decode_htj2k(const Jpeg2000DecoderContext *s, Jpeg2000CodingStyle *c "Cleanup pass length must be at least 2 bytes in length\n"); return AVERROR_INVALIDDATA; } + // this might arise either if the codestream is corrupted; or contains multiple HT Sets + // (see Rec. ITU-T T.814, Annex B.1), which the parser does not currently support + if (Lcup + Lref != cblk->length) + return AVERROR_INVALIDDATA; + Dcup = cblk->data; Dref = cblk->data + Lcup; // Dref comes after the refinement segment @@ -1263,6 +1268,11 @@ ff_jpeg2000_decode_htj2k(const Jpeg2000DecoderContext *s, Jpeg2000CodingStyle *c cblk->zbp = S_blk - 1; pLSB = 30 - S_blk; + if (pLSB <= 1 || pLSB >= 31) { + avpriv_request_sample(s->avctx, "pLSB %d", pLSB); + return AVERROR_PATCHWELCOME; + } + Scup = (Dcup[Lcup - 1] << 4) + (Dcup[Lcup - 2] & 0x0F); if (Scup < 2 || Scup > Lcup || Scup > 4079) { diff --git a/libavcodec/lcevcdec.c b/libavcodec/lcevcdec.c index 601e97b3a..1bfb7c78c 100644 --- a/libavcodec/lcevcdec.c +++ b/libavcodec/lcevcdec.c @@ -16,8 +16,6 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ -#include "config_components.h" - #include "libavutil/avassert.h" #include "libavutil/frame.h" #include "libavutil/imgutils.h" @@ -26,7 +24,6 @@ #include "decode.h" #include "lcevcdec.h" -#if CONFIG_LIBLCEVC_DEC static LCEVC_ColorFormat map_format(int format) { switch (format) { @@ -50,13 +47,12 @@ static int alloc_base_frame(void *logctx, FFLCEVCContext *lcevc, { LCEVC_PictureDesc desc; LCEVC_ColorFormat fmt = map_format(frame->format); - LCEVC_PictureLockHandle lock; - uint8_t *data[4] = { NULL }; - int linesizes[4] = { 0 }; - uint32_t planes; + LCEVC_PicturePlaneDesc planes[AV_VIDEO_MAX_PLANES] = { 0 }; + int width = frame->width - frame->crop_left - frame->crop_right; + int height = frame->height - frame->crop_top - frame->crop_bottom; LCEVC_ReturnCode res; - res = LCEVC_DefaultPictureDesc(&desc, fmt, frame->width, frame->height); + res = LCEVC_DefaultPictureDesc(&desc, fmt, width, height); if (res != LCEVC_Success) return AVERROR_EXTERNAL; @@ -67,36 +63,16 @@ static int alloc_base_frame(void *logctx, FFLCEVCContext *lcevc, desc.sampleAspectRatioNum = frame->sample_aspect_ratio.num; desc.sampleAspectRatioDen = frame->sample_aspect_ratio.den; + for (int i = 0; i < AV_VIDEO_MAX_PLANES; i++) { + planes[i].firstSample = frame->data[i]; + planes[i].rowByteStride = frame->linesize[i]; + } + /* Allocate LCEVC Picture */ - res = LCEVC_AllocPicture(lcevc->decoder, &desc, picture); + res = LCEVC_AllocPictureExternal(lcevc->decoder, &desc, NULL, planes, picture); if (res != LCEVC_Success) { return AVERROR_EXTERNAL; } - res = LCEVC_LockPicture(lcevc->decoder, *picture, LCEVC_Access_Write, &lock); - if (res != LCEVC_Success) - return AVERROR_EXTERNAL; - - res = LCEVC_GetPicturePlaneCount(lcevc->decoder, *picture, &planes); - if (res != LCEVC_Success) - return AVERROR_EXTERNAL; - - for (unsigned i = 0; i < planes; i++) { - LCEVC_PicturePlaneDesc plane; - - res = LCEVC_GetPictureLockPlaneDesc(lcevc->decoder, lock, i, &plane); - if (res != LCEVC_Success) - return AVERROR_EXTERNAL; - - data[i] = plane.firstSample; - linesizes[i] = plane.rowByteStride; - } - - av_image_copy2(data, linesizes, frame->data, frame->linesize, - frame->format, frame->width, frame->height); - - res = LCEVC_UnlockPicture(lcevc->decoder, lock); - if (res != LCEVC_Success) - return AVERROR_EXTERNAL; return 0; } @@ -132,6 +108,7 @@ static int lcevc_send_frame(void *logctx, FFLCEVCFrame *frame_ctx, const AVFrame { FFLCEVCContext *lcevc = frame_ctx->lcevc; const AVFrameSideData *sd = av_frame_get_side_data(in, AV_FRAME_DATA_LCEVC); + AVFrame *opaque; LCEVC_PictureHandle picture; LCEVC_ReturnCode res; int ret = 0; @@ -139,7 +116,11 @@ static int lcevc_send_frame(void *logctx, FFLCEVCFrame *frame_ctx, const AVFrame if (!sd) return 1; +#ifdef LCEVC_DEC_VERSION_MAJOR + res = LCEVC_SendDecoderEnhancementData(lcevc->decoder, in->pts, sd->data, sd->size); +#else res = LCEVC_SendDecoderEnhancementData(lcevc->decoder, in->pts, 0, sd->data, sd->size); +#endif if (res != LCEVC_Success) return AVERROR_EXTERNAL; @@ -147,9 +128,29 @@ static int lcevc_send_frame(void *logctx, FFLCEVCFrame *frame_ctx, const AVFrame if (ret < 0) return ret; - res = LCEVC_SendDecoderBase(lcevc->decoder, in->pts, 0, picture, -1, NULL); - if (res != LCEVC_Success) + opaque = av_frame_clone(in); + if (!opaque) { + LCEVC_FreePicture(lcevc->decoder, picture); + return AVERROR(ENOMEM); + } + + res = LCEVC_SetPictureUserData(lcevc->decoder, picture, opaque); + if (res != LCEVC_Success) { + LCEVC_FreePicture(lcevc->decoder, picture); + av_frame_free(&opaque); return AVERROR_EXTERNAL; + } + +#ifdef LCEVC_DEC_VERSION_MAJOR + res = LCEVC_SendDecoderBase(lcevc->decoder, in->pts, picture, -1, opaque); +#else + res = LCEVC_SendDecoderBase(lcevc->decoder, in->pts, 0, picture, -1, opaque); +#endif + if (res != LCEVC_Success) { + LCEVC_FreePicture(lcevc->decoder, picture); + av_frame_free(&opaque); + return AVERROR_EXTERNAL; + } memset(&picture, 0, sizeof(picture)); ret = alloc_enhanced_frame(logctx, frame_ctx, &picture); @@ -157,8 +158,10 @@ static int lcevc_send_frame(void *logctx, FFLCEVCFrame *frame_ctx, const AVFrame return ret; res = LCEVC_SendDecoderPicture(lcevc->decoder, picture); - if (res != LCEVC_Success) + if (res != LCEVC_Success) { + LCEVC_FreePicture(lcevc->decoder, picture); return AVERROR_EXTERNAL; + } return 0; } @@ -176,8 +179,14 @@ static int generate_output(void *logctx, FFLCEVCFrame *frame_ctx, AVFrame *out) return AVERROR_EXTERNAL; res = LCEVC_GetPictureDesc(lcevc->decoder, picture, &desc); - if (res != LCEVC_Success) + if (res != LCEVC_Success) { + LCEVC_FreePicture(lcevc->decoder, picture); return AVERROR_EXTERNAL; + } + + av_frame_unref(out); + av_frame_copy_props(frame_ctx->frame, (AVFrame *)info.baseUserData); + av_frame_move_ref(out, frame_ctx->frame); out->crop_top = desc.cropTop; out->crop_bottom = desc.cropBottom; @@ -185,11 +194,6 @@ static int generate_output(void *logctx, FFLCEVCFrame *frame_ctx, AVFrame *out) out->crop_right = desc.cropRight; out->sample_aspect_ratio.num = desc.sampleAspectRatioNum; out->sample_aspect_ratio.den = desc.sampleAspectRatioDen; - - av_frame_copy_props(frame_ctx->frame, out); - av_frame_unref(out); - av_frame_move_ref(out, frame_ctx->frame); - out->width = desc.width + out->crop_left + out->crop_right; out->height = desc.height + out->crop_top + out->crop_bottom; @@ -200,18 +204,13 @@ static int generate_output(void *logctx, FFLCEVCFrame *frame_ctx, AVFrame *out) return 0; } -static int lcevc_receive_frame(void *logctx, FFLCEVCFrame *frame_ctx, AVFrame *out) +static int lcevc_flush_pictures(FFLCEVCContext *lcevc) { - FFLCEVCContext *lcevc = frame_ctx->lcevc; LCEVC_PictureHandle picture; LCEVC_ReturnCode res; - int ret; - - ret = generate_output(logctx, frame_ctx, out); - if (ret < 0) - return ret; while (1) { + AVFrame *base = NULL; res = LCEVC_ReceiveDecoderBase (lcevc->decoder, &picture); if (res != LCEVC_Success && res != LCEVC_Again) return AVERROR_EXTERNAL; @@ -219,6 +218,9 @@ static int lcevc_receive_frame(void *logctx, FFLCEVCFrame *frame_ctx, AVFrame *o if (res == LCEVC_Again) break; + LCEVC_GetPictureUserData(lcevc->decoder, picture, (void **)&base); + av_frame_free(&base); + res = LCEVC_FreePicture(lcevc->decoder, picture); if (res != LCEVC_Success) return AVERROR_EXTERNAL; @@ -227,6 +229,18 @@ static int lcevc_receive_frame(void *logctx, FFLCEVCFrame *frame_ctx, AVFrame *o return 0; } +static int lcevc_receive_frame(void *logctx, FFLCEVCFrame *frame_ctx, AVFrame *out) +{ + FFLCEVCContext *lcevc = frame_ctx->lcevc; + int ret; + + ret = generate_output(logctx, frame_ctx, out); + if (ret < 0) + return ret; + + return lcevc_flush_pictures(lcevc); +} + static void event_callback(LCEVC_DecoderHandle dec, LCEVC_Event event, LCEVC_PictureHandle pic, const LCEVC_DecodeInformation *info, const uint8_t *data, uint32_t size, void *logctx) @@ -243,15 +257,16 @@ static void event_callback(LCEVC_DecoderHandle dec, LCEVC_Event event, static void lcevc_free(FFRefStructOpaque unused, void *obj) { FFLCEVCContext *lcevc = obj; - if (lcevc->initialized) + if (lcevc->initialized) { + LCEVC_FlushDecoder(lcevc->decoder); + lcevc_flush_pictures(lcevc); LCEVC_DestroyDecoder(lcevc->decoder); + } memset(lcevc, 0, sizeof(*lcevc)); } -#endif static int lcevc_init(FFLCEVCContext *lcevc, void *logctx) { -#if CONFIG_LIBLCEVC_DEC LCEVC_AccelContextHandle dummy = { 0 }; const int32_t event = LCEVC_Log; @@ -270,7 +285,6 @@ static int lcevc_init(FFLCEVCContext *lcevc, void *logctx) return AVERROR_EXTERNAL; } -#endif lcevc->initialized = 1; return 0; @@ -289,7 +303,6 @@ int ff_lcevc_process(void *logctx, AVFrame *frame) return ret; } -#if CONFIG_LIBLCEVC_DEC av_assert0(frame_ctx->frame); @@ -297,12 +310,11 @@ int ff_lcevc_process(void *logctx, AVFrame *frame) if (ret) return ret < 0 ? ret : 0; - lcevc_receive_frame(logctx, frame_ctx, frame); + ret = lcevc_receive_frame(logctx, frame_ctx, frame); if (ret < 0) return ret; av_frame_remove_side_data(frame, AV_FRAME_DATA_LCEVC); -#endif return 0; } @@ -310,11 +322,9 @@ int ff_lcevc_process(void *logctx, AVFrame *frame) int ff_lcevc_alloc(FFLCEVCContext **plcevc) { FFLCEVCContext *lcevc = NULL; -#if CONFIG_LIBLCEVC_DEC lcevc = ff_refstruct_alloc_ext(sizeof(*lcevc), 0, NULL, lcevc_free); if (!lcevc) return AVERROR(ENOMEM); -#endif *plcevc = lcevc; return 0; } diff --git a/libavcodec/lcldec.c b/libavcodec/lcldec.c index b439dbe25..e9d4283ee 100644 --- a/libavcodec/lcldec.c +++ b/libavcodec/lcldec.c @@ -175,7 +175,7 @@ static int decode_frame(AVCodecContext *avctx, AVFrame *frame, int height = avctx->height; // Real image height unsigned int mszh_dlen; unsigned char yq, y1q, uq, vq; - int uqvq, ret; + int ret; unsigned int mthread_inlen, mthread_outlen; unsigned int len = buf_size; int linesize, offset; @@ -306,7 +306,7 @@ static int decode_frame(AVCodecContext *avctx, AVFrame *frame, for (row = 0; row < height; row++) { pixel_ptr = row * width * 3; yq = encoded[pixel_ptr++]; - uqvq = AV_RL16(encoded+pixel_ptr); + unsigned uqvq = AV_RL16(encoded+pixel_ptr); pixel_ptr += 2; for (col = 1; col < width; col++) { encoded[pixel_ptr] = yq -= encoded[pixel_ptr]; diff --git a/libavcodec/libsvtav1.c b/libavcodec/libsvtav1.c index 43fe531fd..7a3048411 100644 --- a/libavcodec/libsvtav1.c +++ b/libavcodec/libsvtav1.c @@ -238,7 +238,11 @@ static int config_enc_params(EbSvtAv1EncConfiguration *param, } else if (svt_enc->qp > 0) { param->qp = svt_enc->qp; param->rate_control_mode = 0; +#if SVT_AV1_CHECK_VERSION(4, 0, 0) + param->aq_mode = 0; +#else param->enable_adaptive_quantization = 0; +#endif } desc = av_pix_fmt_desc_get(avctx->pix_fmt); diff --git a/libavcodec/lzf.c b/libavcodec/lzf.c index 8f223b1f4..5d6e9925d 100644 --- a/libavcodec/lzf.c +++ b/libavcodec/lzf.c @@ -38,16 +38,15 @@ #define LZF_LONG_BACKREF 7 + 2 -static inline int lzf_realloc(uint8_t **buf, size_t *size, int addition, unsigned *allocated_size) +static inline int lzf_realloc(uint8_t **buf, size_t new_size, unsigned *allocated_size) { - void *ptr = av_fast_realloc(*buf, allocated_size, *size + addition); + void *ptr = av_fast_realloc(*buf, allocated_size, new_size); if (!ptr) { av_freep(buf); //probably not needed return AVERROR(ENOMEM); } *buf = ptr; - *size += addition; return 0; } @@ -63,8 +62,8 @@ int ff_lzf_uncompress(GetByteContext *gb, uint8_t **buf, size_t *size, unsigned if (s < LZF_LITERAL_MAX) { s++; - if (s > *size - len) { - ret = lzf_realloc(buf, size, s, allocated_size); + if (s > *allocated_size - len) { + ret = lzf_realloc(buf, len + s, allocated_size); if (ret < 0) return ret; p = *buf + len; @@ -88,8 +87,8 @@ int ff_lzf_uncompress(GetByteContext *gb, uint8_t **buf, size_t *size, unsigned if (off > len) return AVERROR_INVALIDDATA; - if (l > *size - len) { - ret = lzf_realloc(buf, size, l, allocated_size); + if (l > *allocated_size - len) { + ret = lzf_realloc(buf, len + l, allocated_size); if (ret < 0) return ret; p = *buf + len; diff --git a/libavcodec/magicyuv.c b/libavcodec/magicyuv.c index b85505c42..27095797f 100644 --- a/libavcodec/magicyuv.c +++ b/libavcodec/magicyuv.c @@ -348,7 +348,8 @@ static int magy_decode_slice(AVCodecContext *avctx, void *tdata, s->llviddsp.add_left_pred(dst, dst, width, 0); dst += stride; } - lefttop = left = dst[0]; + if (1 + interlaced < height) + lefttop = left = dst[0]; for (k = 1 + interlaced; k < height; k++) { s->llviddsp.add_median_pred(dst, dst - fake_stride, dst, width, &left, &lefttop); diff --git a/libavcodec/mdec.c b/libavcodec/mdec.c index 5ab40719a..e25af404b 100644 --- a/libavcodec/mdec.c +++ b/libavcodec/mdec.c @@ -175,6 +175,9 @@ static int decode_frame(AVCodecContext *avctx, AVFrame *frame, int buf_size = avpkt->size; int ret; + if (a->mb_width * a->mb_height * 3 > buf_size) + return AVERROR_INVALIDDATA; + if ((ret = ff_thread_get_buffer(avctx, frame, 0)) < 0) return ret; diff --git a/libavcodec/mjpegdec.c b/libavcodec/mjpegdec.c index 94fc0377f..66c98b60b 100644 --- a/libavcodec/mjpegdec.c +++ b/libavcodec/mjpegdec.c @@ -150,7 +150,7 @@ av_cold int ff_mjpeg_decode_init(AVCodecContext *avctx) if ((ret = init_default_huffman_tables(s)) < 0) return ret; - if (s->extern_huff) { + if (s->extern_huff && avctx->extradata) { av_log(avctx, AV_LOG_INFO, "using external huffman table\n"); if ((ret = init_get_bits(&s->gb, avctx->extradata, avctx->extradata_size * 8)) < 0) return ret; @@ -344,9 +344,11 @@ int ff_mjpeg_decode_sof(MJpegDecodeContext *s) if (av_image_check_size(width, height, 0, s->avctx) < 0) return AVERROR_INVALIDDATA; - // A valid frame requires at least 1 bit for DC + 1 bit for AC for each 8x8 block. - if (s->buf_size && (width + 7) / 8 * ((height + 7) / 8) > s->buf_size * 4LL) - return AVERROR_INVALIDDATA; + if (!s->progressive && !s->ls) { + // A valid frame requires at least 1 bit for DC + 1 bit for AC for each 8x8 block. + if (s->buf_size && (width + 7) / 8 * ((height + 7) / 8) > s->buf_size * 4LL) + return AVERROR_INVALIDDATA; + } nb_components = get_bits(&s->gb, 8); if (nb_components <= 0 || diff --git a/libavcodec/mpegaudiodsp_template.c b/libavcodec/mpegaudiodsp_template.c index fbbd94e48..6e8b84664 100644 --- a/libavcodec/mpegaudiodsp_template.c +++ b/libavcodec/mpegaudiodsp_template.c @@ -369,4 +369,3 @@ void RENAME(ff_imdct36_blocks)(INTFLOAT *out, INTFLOAT *buf, INTFLOAT *in, out++; } } - diff --git a/libavcodec/mpegaudioenc_template.c b/libavcodec/mpegaudioenc_template.c index 396e8a489..adb88cd68 100644 --- a/libavcodec/mpegaudioenc_template.c +++ b/libavcodec/mpegaudioenc_template.c @@ -778,4 +778,3 @@ static const FFCodecDefault mp2_defaults[] = { { "b", "0" }, { NULL }, }; - diff --git a/libavcodec/mpegvideo_enc.c b/libavcodec/mpegvideo_enc.c index 74b598d08..3dd486518 100644 --- a/libavcodec/mpegvideo_enc.c +++ b/libavcodec/mpegvideo_enc.c @@ -2809,7 +2809,7 @@ static void write_mb_info(MpegEncContext *s) bytestream_put_byte(&ptr, 0); /* vmv2 */ } -static void update_mb_info(MpegEncContext *s, int startcode) +static void update_mb_info(MpegEncContext *s) { if (!s->mb_info) return; @@ -2817,14 +2817,6 @@ static void update_mb_info(MpegEncContext *s, int startcode) s->mb_info_size += 12; s->prev_mb_info = s->last_mb_info; } - if (startcode) { - s->prev_mb_info = put_bytes_count(&s->pb, 0); - /* This might have incremented mb_info_size above, and we return without - * actually writing any info into that slot yet. But in that case, - * this will be called again at the start of the after writing the - * start code, actually writing the mb info. */ - return; - } s->last_mb_info = put_bytes_count(&s->pb, 0); if (!s->mb_info_size) @@ -3040,8 +3032,11 @@ static int encode_thread(AVCodecContext *c, void *arg){ case AV_CODEC_ID_H263: case AV_CODEC_ID_H263P: if (CONFIG_H263_ENCODER) { - update_mb_info(s, 1); + if (s->mb_info && put_bytes_count(&s->pb, 0) - s->prev_mb_info >= s->mb_info) + s->mb_info_size += 12; + ff_h263_encode_gob_header(s, mb_y); + s->prev_mb_info = put_bits_count(&s->pb)/8; } break; } @@ -3067,7 +3062,7 @@ static int encode_thread(AVCodecContext *c, void *arg){ s->mb_skipped=0; s->dquant=0; //only for QP_RD - update_mb_info(s, 0); + update_mb_info(s); if (mb_type & (mb_type-1) || (s->mpv_flags & FF_MPV_FLAG_QP_RD)) { // more than 1 MB type possible or FF_MPV_FLAG_QP_RD int next_block=0; diff --git a/libavcodec/mpv_reconstruct_mb_template.c b/libavcodec/mpv_reconstruct_mb_template.c index dca982ae0..50f76fa22 100644 --- a/libavcodec/mpv_reconstruct_mb_template.c +++ b/libavcodec/mpv_reconstruct_mb_template.c @@ -282,4 +282,3 @@ void mpv_reconstruct_mb_internal(MpegEncContext *s, int16_t block[12][64], } } } - diff --git a/libavcodec/msmpeg4.c b/libavcodec/msmpeg4.c index 872dc8db6..01e6f3ccc 100644 --- a/libavcodec/msmpeg4.c +++ b/libavcodec/msmpeg4.c @@ -336,4 +336,3 @@ int ff_msmpeg4_pred_dc(MpegEncContext *s, int n, *dc_val_ptr = &dc_val[0]; return pred; } - diff --git a/libavcodec/notchlc.c b/libavcodec/notchlc.c index d99de1810..695c1d50f 100644 --- a/libavcodec/notchlc.c +++ b/libavcodec/notchlc.c @@ -79,7 +79,7 @@ static int lz4_decompress(AVCodecContext *avctx, PutByteContext *pb) { unsigned reference_pos, delta, pos = 0; - uint8_t history[64 * 1024]; + uint8_t history[64 * 1024] = { 0 }; int match_length; while (bytestream2_get_bytes_left(gb) > 0) { @@ -90,6 +90,8 @@ static int lz4_decompress(AVCodecContext *avctx, unsigned char current; do { current = bytestream2_get_byte(gb); + if (current > INT_MAX - num_literals) + return AVERROR_INVALIDDATA; num_literals += current; } while (current == 255); } @@ -122,6 +124,8 @@ static int lz4_decompress(AVCodecContext *avctx, do { current = bytestream2_get_byte(gb); + if (current > INT_MAX - match_length) + return AVERROR_INVALIDDATA; match_length += current; } while (current == 255); } diff --git a/libavcodec/omx.c b/libavcodec/omx.c index 2c3865506..2b9fa636f 100644 --- a/libavcodec/omx.c +++ b/libavcodec/omx.c @@ -684,6 +684,11 @@ static av_cold int omx_encode_init(AVCodecContext *avctx) buffer = get_buffer(&s->output_mutex, &s->output_cond, &s->num_done_out_buffers, s->done_out_buffers, 1); if (buffer->nFlags & OMX_BUFFERFLAG_CODECCONFIG) { + if (buffer->nFilledLen > INT32_MAX - AV_INPUT_BUFFER_PADDING_SIZE - avctx->extradata_size) { + ret = AVERROR(ENOMEM); + goto fail; + } + if ((ret = av_reallocp(&avctx->extradata, avctx->extradata_size + buffer->nFilledLen + AV_INPUT_BUFFER_PADDING_SIZE)) < 0) { avctx->extradata_size = 0; goto fail; diff --git a/libavcodec/opus/parse.c b/libavcodec/opus/parse.c index 78a2a75fc..687199b1b 100644 --- a/libavcodec/opus/parse.c +++ b/libavcodec/opus/parse.c @@ -466,4 +466,3 @@ fail: av_channel_layout_uninit(&layout); return ret; } - diff --git a/libavcodec/pdvdec.c b/libavcodec/pdvdec.c index e2c03e7e0..dae9f63cc 100644 --- a/libavcodec/pdvdec.c +++ b/libavcodec/pdvdec.c @@ -75,6 +75,9 @@ static int decode_frame(AVCodecContext *avctx, AVFrame *frame, return AVERROR_INVALIDDATA; } + if (avpkt->size * 1032LL < ((avctx->width + 7) >> 3) * avctx->height) //Asymptotic max compression of deflate + return AVERROR_INVALIDDATA; + if ((ret = ff_get_buffer(avctx, frame, AV_GET_BUFFER_FLAG_REF)) < 0) return ret; diff --git a/libavcodec/pnmdec.c b/libavcodec/pnmdec.c index 59013ada4..61fb994b9 100644 --- a/libavcodec/pnmdec.c +++ b/libavcodec/pnmdec.c @@ -62,6 +62,9 @@ static int pnm_decode_frame(AVCodecContext *avctx, AVFrame *p, if (avctx->skip_frame >= AVDISCARD_ALL) return avpkt->size; + if (avctx->width * avctx->height / 8 > s->bytestream_end - s->bytestream) + return AVERROR_INVALIDDATA; + if ((ret = ff_get_buffer(avctx, p, 0)) < 0) return ret; avctx->bits_per_raw_sample = av_log2(s->maxval) + 1; diff --git a/libavcodec/qdm2.c b/libavcodec/qdm2.c index e629e3b42..b4aaf179f 100644 --- a/libavcodec/qdm2.c +++ b/libavcodec/qdm2.c @@ -1857,6 +1857,8 @@ static int qdm2_decode_frame(AVCodecContext *avctx, AVFrame *frame, if(buf_size < s->checksum_size) return -1; + s->sub_packet = 0; + /* get output buffer */ frame->nb_samples = 16 * s->frame_size; if ((ret = ff_get_buffer(avctx, frame, 0)) < 0) diff --git a/libavcodec/ralf.c b/libavcodec/ralf.c index 8f7fac793..36ad51fab 100644 --- a/libavcodec/ralf.c +++ b/libavcodec/ralf.c @@ -157,6 +157,7 @@ static av_cold int decode_init(AVCodecContext *avctx) if (ctx->max_frame_size > (1 << 20) || !ctx->max_frame_size) { av_log(avctx, AV_LOG_ERROR, "invalid frame size %d\n", ctx->max_frame_size); + return AVERROR_INVALIDDATA; } ctx->max_frame_size = FFMAX(ctx->max_frame_size, avctx->sample_rate); diff --git a/libavcodec/rasc.c b/libavcodec/rasc.c index 7b0251ca3..4f5a30092 100644 --- a/libavcodec/rasc.c +++ b/libavcodec/rasc.c @@ -51,6 +51,8 @@ typedef struct RASCContext { GetByteContext gb; uint8_t *delta; int delta_size; + uint8_t *mv_scratch; + unsigned int mv_scratch_size; uint8_t *cursor; int cursor_size; unsigned cursor_w; @@ -294,10 +296,8 @@ static int decode_move(AVCodecContext *avctx, b2 -= s->frame2->linesize[0]; } } else if (type == 0) { - uint8_t *buffer; - - av_fast_padded_malloc(&s->delta, &s->delta_size, w * h * s->bpp); - buffer = s->delta; + av_fast_padded_malloc(&s->mv_scratch, &s->mv_scratch_size, w * h * s->bpp); + uint8_t *buffer = s->mv_scratch; if (!buffer) return AVERROR(ENOMEM); @@ -772,6 +772,8 @@ static av_cold int decode_close(AVCodecContext *avctx) s->cursor_size = 0; av_freep(&s->delta); s->delta_size = 0; + av_freep(&s->mv_scratch); + s->mv_scratch_size = 0; av_frame_free(&s->frame1); av_frame_free(&s->frame2); ff_inflate_end(&s->zstream); diff --git a/libavcodec/snow_dwt.c b/libavcodec/snow_dwt.c index 1250597ee..26a8b9adc 100644 --- a/libavcodec/snow_dwt.c +++ b/libavcodec/snow_dwt.c @@ -858,5 +858,3 @@ av_cold void ff_dwt_init(SnowDWTContext *c) ff_dwt_init_x86(c); #endif } - - diff --git a/libavcodec/snowenc.c b/libavcodec/snowenc.c index 0623c9d19..58dd7017c 100644 --- a/libavcodec/snowenc.c +++ b/libavcodec/snowenc.c @@ -70,6 +70,8 @@ typedef struct SnowEncContext { uint64_t encoding_error[SNOW_MAX_PLANES]; } SnowEncContext; +#define PTR_ADD(ptr, off) ((ptr) ? (ptr) + (off) : NULL) + static void init_ref(MotionEstContext *c, const uint8_t *const src[3], uint8_t *const ref[3], uint8_t *const ref2[3], int x, int y, int ref_index) @@ -82,7 +84,7 @@ static void init_ref(MotionEstContext *c, const uint8_t *const src[3], }; for (int i = 0; i < 3; i++) { c->src[0][i] = src [i]; - c->ref[0][i] = ref [i] + offset[i]; + c->ref[0][i] = PTR_ADD(ref[i], offset[i]); } av_assert2(!ref_index); } @@ -400,8 +402,8 @@ static int encode_q_branch(SnowEncContext *enc, int level, int x, int y) const int stride= s->current_picture->linesize[0]; const int uvstride= s->current_picture->linesize[1]; const uint8_t *const current_data[3] = { s->input_picture->data[0] + (x + y* stride)*block_w, - s->input_picture->data[1] + ((x*block_w)>>s->chroma_h_shift) + ((y*uvstride*block_w)>>s->chroma_v_shift), - s->input_picture->data[2] + ((x*block_w)>>s->chroma_h_shift) + ((y*uvstride*block_w)>>s->chroma_v_shift)}; + PTR_ADD(s->input_picture->data[1], ((x*block_w)>>s->chroma_h_shift) + ((y*uvstride*block_w)>>s->chroma_v_shift)), + PTR_ADD(s->input_picture->data[2], ((x*block_w)>>s->chroma_h_shift) + ((y*uvstride*block_w)>>s->chroma_v_shift))}; int P[10][2]; int16_t last_mv[3][2]; int qpel= !!(s->avctx->flags & AV_CODEC_FLAG_QPEL); //unused diff --git a/libavcodec/svq1dec.c b/libavcodec/svq1dec.c index 57cac8ee7..3a508849a 100644 --- a/libavcodec/svq1dec.c +++ b/libavcodec/svq1dec.c @@ -695,6 +695,11 @@ static int svq1_decode_frame(AVCodecContext *avctx, AVFrame *cur, avctx->skip_frame >= AVDISCARD_ALL) return buf_size; + // Reject obviously too-small packets early: require at least one remaining bit per aligned luma macroblock. + // FFALIGN(s->width, 16) * FFALIGN(s->height, 16) / 256 represent the number of Macroblocks + if (get_bits_left(&s->gb) < FFALIGN(s->width, 16) * FFALIGN(s->height, 16) / 256) + return AVERROR_INVALIDDATA; + result = ff_get_buffer(avctx, cur, s->nonref ? 0 : AV_GET_BUFFER_FLAG_REF); if (result < 0) return result; diff --git a/libavcodec/tableprint_vlc.h b/libavcodec/tableprint_vlc.h index b97c1f9cf..e42bf08a7 100644 --- a/libavcodec/tableprint_vlc.h +++ b/libavcodec/tableprint_vlc.h @@ -27,7 +27,7 @@ #define av_log(a, ...) while(0) #define ff_dlog(a, ...) while(0) #define AVUTIL_MEM_H -#define av_malloc(s) NULL +#define av_mallocz(s) NULL #define av_malloc_array(a, b) NULL #define av_realloc_f(p, o, n) NULL #define av_free(p) while(0) diff --git a/libavcodec/tdsc.c b/libavcodec/tdsc.c index ab0a70859..b65f81a4a 100644 --- a/libavcodec/tdsc.c +++ b/libavcodec/tdsc.c @@ -242,7 +242,6 @@ static int tdsc_load_cursor(AVCodecContext *avctx) bits <<= 1; } } - dst += ctx->cursor_stride - ctx->cursor_w * 4; } dst = ctx->cursor; @@ -274,7 +273,6 @@ static int tdsc_load_cursor(AVCodecContext *avctx) bits <<= 1; } } - dst += ctx->cursor_stride - ctx->cursor_w * 4; } break; case CUR_FMT_BGRA: @@ -360,7 +358,8 @@ static int tdsc_decode_jpeg_tile(AVCodecContext *avctx, int tile_size, } ret = avcodec_receive_frame(ctx->jpeg_avctx, ctx->jpgframe); - if (ret < 0 || ctx->jpgframe->format != AV_PIX_FMT_YUVJ420P) { + if (ret < 0 || ctx->jpgframe->format != AV_PIX_FMT_YUVJ420P || + w > ctx->jpgframe->width || h > ctx->jpgframe->height) { av_log(avctx, AV_LOG_ERROR, "JPEG decoding error (%d).\n", ret); @@ -404,7 +403,7 @@ static int tdsc_decode_tiles(AVCodecContext *avctx, int number_tiles) } tile_size = bytestream2_get_le32(&ctx->gbc); - if (bytestream2_get_bytes_left(&ctx->gbc) < tile_size) + if (bytestream2_get_bytes_left(&ctx->gbc) < tile_size + 24LL) return AVERROR_INVALIDDATA; tile_mode = bytestream2_get_le32(&ctx->gbc); @@ -437,6 +436,9 @@ static int tdsc_decode_tiles(AVCodecContext *avctx, int number_tiles) if (ret < 0) return ret; } else if (tile_mode == MKTAG(' ','W','A','R')) { + if (3LL * w * h > tile_size) + return AVERROR_INVALIDDATA; + /* Just copy the buffer to output */ av_image_copy_plane(ctx->refframe->data[0] + x * 3 + ctx->refframe->linesize[0] * y, diff --git a/libavcodec/tmv.c b/libavcodec/tmv.c index 2ff1424bd..713a7928c 100644 --- a/libavcodec/tmv.c +++ b/libavcodec/tmv.c @@ -46,9 +46,6 @@ static int tmv_decode_frame(AVCodecContext *avctx, AVFrame *frame, unsigned x, y, fg, bg, c; int ret; - if ((ret = ff_get_buffer(avctx, frame, 0)) < 0) - return ret; - if (avpkt->size < 2*char_rows*char_cols) { av_log(avctx, AV_LOG_ERROR, "Input buffer too small, truncated sample?\n"); @@ -56,6 +53,9 @@ static int tmv_decode_frame(AVCodecContext *avctx, AVFrame *frame, return AVERROR_INVALIDDATA; } + if ((ret = ff_get_buffer(avctx, frame, 0)) < 0) + return ret; + dst = frame->data[0]; #if FF_API_PALETTE_HAS_CHANGED diff --git a/libavcodec/utils.c b/libavcodec/utils.c index 6909a5ba2..aeb8f2f09 100644 --- a/libavcodec/utils.c +++ b/libavcodec/utils.c @@ -640,16 +640,16 @@ static int get_audio_frame_duration(enum AVCodecID id, int sr, int ch, int ba, if (frame_bytes > 0) { /* calc from frame_bytes only */ - if (id == AV_CODEC_ID_TRUESPEECH) - return 240 * (frame_bytes / 32); - if (id == AV_CODEC_ID_NELLYMOSER) - return 256 * (frame_bytes / 64); - if (id == AV_CODEC_ID_RA_144) - return 160 * (frame_bytes / 20); - if (id == AV_CODEC_ID_APTX) - return 4 * (frame_bytes / 4); - if (id == AV_CODEC_ID_APTX_HD) - return 4 * (frame_bytes / 6); + int64_t d = INT64_MIN; + switch(id) { + case AV_CODEC_ID_TRUESPEECH : d = 240LL * (frame_bytes / 32); break; + case AV_CODEC_ID_NELLYMOSER : d = 256LL * (frame_bytes / 64); break; + case AV_CODEC_ID_RA_144 : d = 160LL * (frame_bytes / 20); break; + case AV_CODEC_ID_APTX : d = 4LL * (frame_bytes / 4); break; + case AV_CODEC_ID_APTX_HD : d = 4LL * (frame_bytes / 6); break; + } + if (d > INT64_MIN) + return ((int)d == d && d > 0) ? d : 0; if (bps > 0) { /* calc from frame_bytes and bits_per_coded_sample */ diff --git a/libavcodec/videotoolbox_vp9.c b/libavcodec/videotoolbox_vp9.c index 3c7494791..232468d51 100644 --- a/libavcodec/videotoolbox_vp9.c +++ b/libavcodec/videotoolbox_vp9.c @@ -83,7 +83,7 @@ CFDataRef ff_videotoolbox_vpcc_extradata_create(AVCodecContext *avctx) p = vt_extradata; *p++ = 1; /* version */ - AV_WB24(p + 1, 0); /* flags */ + AV_WB24(p, 0); /* flags */ p += 3; *p++ = h->h.profile; diff --git a/libavcodec/videotoolboxenc.c b/libavcodec/videotoolboxenc.c index da7b291b0..69656ccb5 100644 --- a/libavcodec/videotoolboxenc.c +++ b/libavcodec/videotoolboxenc.c @@ -2119,7 +2119,7 @@ static int copy_replace_length_codes( uint8_t *new_sei; old_sei_length = find_sei_end(avctx, dst_box, box_len, &new_sei); if (old_sei_length < 0) - return status; + return old_sei_length; wrote_bytes = write_sei(sei, SEI_TYPE_USER_DATA_REGISTERED_ITU_T_T35, diff --git a/libavcodec/vp3.c b/libavcodec/vp3.c index d03a1c9db..1bee221bc 100644 --- a/libavcodec/vp3.c +++ b/libavcodec/vp3.c @@ -46,7 +46,6 @@ #include "decode.h" #include "get_bits.h" #include "hpeldsp.h" -#include "internal.h" #include "jpegquanttables.h" #include "mathops.h" #include "progressframe.h" @@ -2458,7 +2457,7 @@ static av_cold int vp3_decode_init(AVCodecContext *avctx) } } - if (!avctx->internal->is_copy) { + if (ff_thread_sync_ref(avctx, offsetof(Vp3DecodeContext, coeff_vlc)) != FF_THREAD_IS_COPY) { CoeffVLCs *vlcs = ff_refstruct_alloc_ext(sizeof(*s->coeff_vlc), 0, NULL, free_vlc_tables); if (!vlcs) @@ -2527,8 +2526,6 @@ static int vp3_update_thread_context(AVCodecContext *dst, const AVCodecContext * const Vp3DecodeContext *s1 = src->priv_data; int qps_changed = 0; - ff_refstruct_replace(&s->coeff_vlc, s1->coeff_vlc); - // copy previous frame data ref_frames(s, s1); if (!s1->current_frame.f || @@ -2899,6 +2896,8 @@ static int theora_decode_header(AVCodecContext *avctx, GetBitContext *gb) if (av_image_check_size(visible_width, visible_height, 0, avctx) < 0 || visible_width + offset_x > s->width || visible_height + offset_y > s->height || + visible_width + 512 < s->width || + visible_height + 512 < s->height || visible_width < 18 ) { av_log(avctx, AV_LOG_ERROR, diff --git a/libavcodec/vp9.c b/libavcodec/vp9.c index 8ede2e2eb..ba4e40377 100644 --- a/libavcodec/vp9.c +++ b/libavcodec/vp9.c @@ -171,10 +171,12 @@ static int update_size(AVCodecContext *avctx, int w, int h) uint8_t *p; int bytesperpixel = s->bytesperpixel, ret, cols, rows; int lflvl_len, i; + int changed = 0; av_assert0(w > 0 && h > 0); if (!(s->pix_fmt == s->gf_fmt && w == s->w && h == s->h)) { + changed = 1; if ((ret = ff_set_dimensions(avctx, w, h)) < 0) return ret; @@ -235,8 +237,10 @@ static int update_size(AVCodecContext *avctx, int w, int h) *fmtp = AV_PIX_FMT_NONE; ret = ff_get_format(avctx, pix_fmts); - if (ret < 0) + if (ret < 0) { + ff_set_dimensions(avctx, s->w, s->h); return ret; + } avctx->pix_fmt = ret; s->gf_fmt = s->pix_fmt; @@ -248,7 +252,7 @@ static int update_size(AVCodecContext *avctx, int w, int h) rows = (h + 7) >> 3; if (s->intra_pred_data[0] && cols == s->cols && rows == s->rows && s->pix_fmt == s->last_fmt) - return 0; + return changed; s->last_fmt = s->pix_fmt; s->sb_cols = (w + 63) >> 6; @@ -293,9 +297,10 @@ static int update_size(AVCodecContext *avctx, int w, int h) ff_vp9dsp_init(&s->dsp, s->s.h.bpp, avctx->flags & AV_CODEC_FLAG_BITEXACT); ff_videodsp_init(&s->vdsp, s->s.h.bpp); s->last_bpp = s->s.h.bpp; + changed = 1; } - return 0; + return changed; } static int update_block_buffers(AVCodecContext *avctx) @@ -502,6 +507,7 @@ static int decode_frame_header(AVCodecContext *avctx, int c, i, j, k, l, m, n, w, h, max, size2, ret, sharp; int last_invisible; const uint8_t *data2; + int changed; /* general header */ if ((ret = init_get_bits8(&s->gb, data, size)) < 0) { @@ -767,10 +773,10 @@ static int decode_frame_header(AVCodecContext *avctx, } /* tiling info */ - if ((ret = update_size(avctx, w, h)) < 0) { + if ((changed = update_size(avctx, w, h)) < 0) { av_log(avctx, AV_LOG_ERROR, "Failed to initialize decoder for %dx%d @ %d\n", w, h, s->pix_fmt); - return ret; + return changed; } for (s->s.h.tiling.log2_tile_cols = 0; s->sb_cols > (64 << s->s.h.tiling.log2_tile_cols); @@ -785,7 +791,7 @@ static int decode_frame_header(AVCodecContext *avctx, } s->s.h.tiling.log2_tile_rows = decode012(&s->gb); s->s.h.tiling.tile_rows = 1 << s->s.h.tiling.log2_tile_rows; - if (s->s.h.tiling.tile_cols != (1 << s->s.h.tiling.log2_tile_cols)) { + if (s->s.h.tiling.tile_cols != (1 << s->s.h.tiling.log2_tile_cols) || changed) { int n_range_coders; VPXRangeCoder *rc; diff --git a/libavcodec/vvc/intra.c b/libavcodec/vvc/intra.c index c08e79df7..e04129d3b 100644 --- a/libavcodec/vvc/intra.c +++ b/libavcodec/vvc/intra.c @@ -693,4 +693,3 @@ int ff_vvc_reconstruct(VVCLocalContext *lc, const int rs, const int rx, const in ff_vvc_ctu_free_cus(fc->tab.cus + rs); return ret; } - diff --git a/libavcodec/wmaenc.c b/libavcodec/wmaenc.c index 6949f08fb..a5ed25ed1 100644 --- a/libavcodec/wmaenc.c +++ b/libavcodec/wmaenc.c @@ -65,14 +65,14 @@ static av_cold int encode_init(AVCodecContext *avctx) flags1 = 0; flags2 = 1; if (avctx->codec->id == AV_CODEC_ID_WMAV1) { - extradata = av_malloc(4); + extradata = av_mallocz(4 + AV_INPUT_BUFFER_PADDING_SIZE); if (!extradata) return AVERROR(ENOMEM); avctx->extradata_size = 4; AV_WL16(extradata, flags1); AV_WL16(extradata + 2, flags2); } else if (avctx->codec->id == AV_CODEC_ID_WMAV2) { - extradata = av_mallocz(10); + extradata = av_mallocz(10 + AV_INPUT_BUFFER_PADDING_SIZE); if (!extradata) return AVERROR(ENOMEM); avctx->extradata_size = 10; diff --git a/libavcodec/x86/fmtconvert.asm b/libavcodec/x86/fmtconvert.asm index e70df4662..99c5efeab 100644 --- a/libavcodec/x86/fmtconvert.asm +++ b/libavcodec/x86/fmtconvert.asm @@ -85,4 +85,3 @@ cglobal int32_to_float_fmul_array8, 5, 5, 5, c, dst, src, mul, len INIT_XMM sse2 INT32_TO_FLOAT_FMUL_ARRAY8 - diff --git a/libavcodec/x86/mpegvideoencdsp.asm b/libavcodec/x86/mpegvideoencdsp.asm index c73b359c4..d12646ae5 100644 --- a/libavcodec/x86/mpegvideoencdsp.asm +++ b/libavcodec/x86/mpegvideoencdsp.asm @@ -104,4 +104,3 @@ cglobal pix_norm1, 2, 3, %1 INIT_XMM sse2 PIX_NORM1 6, 8 - diff --git a/libavcodec/xxan.c b/libavcodec/xxan.c index cb6a97c66..60d2c4007 100644 --- a/libavcodec/xxan.c +++ b/libavcodec/xxan.c @@ -68,7 +68,7 @@ static av_cold int xan_decode_init(AVCodecContext *avctx) } s->buffer_size = avctx->width * avctx->height; - s->y_buffer = av_malloc(s->buffer_size); + s->y_buffer = av_mallocz(s->buffer_size); if (!s->y_buffer) return AVERROR(ENOMEM); s->scratch_buffer = av_malloc(s->buffer_size + 130); diff --git a/libavcodec/zmbv.c b/libavcodec/zmbv.c index 2c09ccbd7..6ece6e301 100644 --- a/libavcodec/zmbv.c +++ b/libavcodec/zmbv.c @@ -138,6 +138,8 @@ static int zmbv_decode_xor_8(ZmbvContext *c) } if (d) { /* apply XOR'ed difference */ + if (c->decomp_len - (src - c->decomp_buf) < bw2 * bh2) + return AVERROR_INVALIDDATA; out = output + x; for (j = 0; j < bh2; j++) { for (i = 0; i < bw2; i++) @@ -212,6 +214,8 @@ static int zmbv_decode_xor_16(ZmbvContext *c) } if (d) { /* apply XOR'ed difference */ + if (c->decomp_len - (src - c->decomp_buf) < bw2 * bh2 * 2) + return AVERROR_INVALIDDATA; out = output + x; for (j = 0; j < bh2; j++){ for (i = 0; i < bw2; i++) { @@ -296,6 +300,8 @@ static int zmbv_decode_xor_24(ZmbvContext *c) } if (d) { /* apply XOR'ed difference */ + if (c->decomp_len - (src - c->decomp_buf) < bw2 * bh2 * 3) + return AVERROR_INVALIDDATA; out = output + x * 3; for (j = 0; j < bh2; j++) { for (i = 0; i < bw2; i++) { @@ -374,6 +380,8 @@ static int zmbv_decode_xor_32(ZmbvContext *c) } if (d) { /* apply XOR'ed difference */ + if (c->decomp_len - (src - c->decomp_buf) < bw2 * bh2 * 4) + return AVERROR_INVALIDDATA; out = output + x; for (j = 0; j < bh2; j++){ for (i = 0; i < bw2; i++) { @@ -568,8 +576,10 @@ static int decode_frame(AVCodecContext *avctx, AVFrame *frame, frame->pict_type = AV_PICTURE_TYPE_P; if (c->decomp_len < 2LL * ((c->width + c->bw - 1) / c->bw) * ((c->height + c->bh - 1) / c->bh)) return AVERROR_INVALIDDATA; - if (c->decomp_len) - c->decode_xor(c); + if (c->decomp_len) { + if ((ret = c->decode_xor(c)) < 0) + return ret; + } } /* update frames */ diff --git a/libavdevice/gdigrab.c b/libavdevice/gdigrab.c index 08a41c304..fa9ba27db 100644 --- a/libavdevice/gdigrab.c +++ b/libavdevice/gdigrab.c @@ -279,7 +279,7 @@ gdigrab_read_header(AVFormatContext *s1) char *p; name = filename + 5; - hwnd = (HWND) strtoull(name, &p, 0); + hwnd = (HWND)(intptr_t) strtoull(name, &p, 0); if (p == NULL || p == name || p[0] != '\0') { diff --git a/libavfilter/aarch64/vf_bwdif_init_aarch64.c b/libavfilter/aarch64/vf_bwdif_init_aarch64.c index 74530ed5b..efcb31eff 100644 --- a/libavfilter/aarch64/vf_bwdif_init_aarch64.c +++ b/libavfilter/aarch64/vf_bwdif_init_aarch64.c @@ -122,4 +122,3 @@ ff_bwdif_init_aarch64(BWDIFDSPContext *s, int bit_depth) s->filter_edge = filter_edge_helper; s->filter_line3 = filter_line3_helper; } - diff --git a/libavfilter/af_amerge.c b/libavfilter/af_amerge.c index 16507299b..dccbbd841 100644 --- a/libavfilter/af_amerge.c +++ b/libavfilter/af_amerge.c @@ -77,7 +77,7 @@ static int query_formats(AVFilterContext *ctx) AVChannelLayout *inlayout[SWR_CH_MAX] = { NULL }, outlayout = { 0 }; uint64_t outmask = 0; AVFilterChannelLayouts *layouts; - int i, ret, overlap = 0, nb_ch = 0; + int i, ret, nb_ch = 0; for (i = 0; i < s->nb_inputs; i++) { if (!ctx->inputs[i]->incfg.channel_layouts || @@ -92,15 +92,11 @@ static int query_formats(AVFilterContext *ctx) av_channel_layout_describe(inlayout[i], buf, sizeof(buf)); av_log(ctx, AV_LOG_INFO, "Using \"%s\" for input %d\n", buf, i + 1); } - s->in[i].nb_ch = FF_LAYOUT2COUNT(inlayout[i]); - if (s->in[i].nb_ch) { - overlap++; - } else { - s->in[i].nb_ch = inlayout[i]->nb_channels; - if (av_channel_layout_subset(inlayout[i], outmask)) - overlap++; - outmask |= inlayout[i]->order == AV_CHANNEL_ORDER_NATIVE ? - inlayout[i]->u.mask : 0; + s->in[i].nb_ch = inlayout[i]->nb_channels; + for (int j = 0; j < s->in[i].nb_ch; j++) { + enum AVChannel id = av_channel_layout_channel_from_index(inlayout[i], j); + if (id >= 0 && id < 64) + outmask |= (1ULL << id); } nb_ch += s->in[i].nb_ch; } @@ -108,7 +104,7 @@ static int query_formats(AVFilterContext *ctx) av_log(ctx, AV_LOG_ERROR, "Too many channels (max %d)\n", SWR_CH_MAX); return AVERROR(EINVAL); } - if (overlap) { + if (av_popcount64(outmask) != nb_ch) { av_log(ctx, AV_LOG_WARNING, "Input channel layouts overlap: " "output layout will be determined by the number of distinct input channels\n"); diff --git a/libavfilter/af_lv2.c b/libavfilter/af_lv2.c index db9b1e363..adb153523 100644 --- a/libavfilter/af_lv2.c +++ b/libavfilter/af_lv2.c @@ -74,6 +74,7 @@ typedef struct LV2Context { float *controls; LilvInstance *instance; + int instance_activated; LilvNode *atom_AtomPort; LilvNode *atom_Sequence; @@ -386,6 +387,9 @@ static int config_output(AVFilterLink *outlink) inlink->min_samples = inlink->max_samples = 4096; } + lilv_instance_activate(s->instance); + s->instance_activated = 1; + return 0; } @@ -561,6 +565,8 @@ static av_cold void uninit(AVFilterContext *ctx) { LV2Context *s = ctx->priv; + if (s->instance_activated) + lilv_instance_deactivate(s->instance); lilv_node_free(s->powerOf2BlockLength); lilv_node_free(s->fixedBlockLength); lilv_node_free(s->boundedBlockLength); diff --git a/libavfilter/af_pan.c b/libavfilter/af_pan.c index 5feb2439c..13c7d517e 100644 --- a/libavfilter/af_pan.c +++ b/libavfilter/af_pan.c @@ -70,7 +70,7 @@ static int parse_channel_name(char **arg, int *rchannel, int *rnamed) skip_spaces(arg); /* try to parse a channel name, e.g. "FL" */ - if (sscanf(*arg, "%7[A-Z]%n", buf, &len)) { + if (sscanf(*arg, "%7[A-Z]%n", buf, &len) >= 1) { channel_id = av_channel_from_string(buf); if (channel_id < 0) return channel_id; @@ -81,7 +81,7 @@ static int parse_channel_name(char **arg, int *rchannel, int *rnamed) return 0; } /* try to parse a channel number, e.g. "c2" */ - if (sscanf(*arg, "c%d%n", &channel_id, &len) && + if (sscanf(*arg, "c%d%n", &channel_id, &len) >= 1 && channel_id >= 0 && channel_id < MAX_CHANNELS) { *rchannel = channel_id; *rnamed = 0; diff --git a/libavfilter/avf_showcwt.c b/libavfilter/avf_showcwt.c index 760a07f2f..f26b89a81 100644 --- a/libavfilter/avf_showcwt.c +++ b/libavfilter/avf_showcwt.c @@ -1021,7 +1021,7 @@ static int config_output(AVFilterLink *outlink) break; case DIRECTION_RL: case DIRECTION_DU: - s->pos = s->sono_size; + s->pos = FFMAX(s->sono_size - 1, 0); break; } @@ -1096,7 +1096,7 @@ static int output_frame(AVFilterContext *ctx) case DIRECTION_RL: s->pos--; if (s->pos < 0) { - s->pos = s->sono_size; + s->pos = FFMAX(s->sono_size - 1, 0); s->new_frame = 1; } break; @@ -1110,7 +1110,7 @@ static int output_frame(AVFilterContext *ctx) case DIRECTION_DU: s->pos--; if (s->pos < 0) { - s->pos = s->sono_size; + s->pos = FFMAX(s->sono_size - 1, 0); s->new_frame = 1; } break; @@ -1124,7 +1124,7 @@ static int output_frame(AVFilterContext *ctx) break; case DIRECTION_RL: case DIRECTION_DU: - s->pos = s->sono_size; + s->pos = FFMAX(s->sono_size - 1, 0); break; } break; diff --git a/libavfilter/buffersrc.c b/libavfilter/buffersrc.c index ec5898fcf..f9b206194 100644 --- a/libavfilter/buffersrc.c +++ b/libavfilter/buffersrc.c @@ -283,6 +283,16 @@ int av_buffersrc_close(AVFilterContext *ctx, int64_t pts, unsigned flags) return (flags & AV_BUFFERSRC_FLAG_PUSH) ? push_frame(ctx->graph) : 0; } +int av_buffersrc_get_status(AVFilterContext *ctx) +{ + BufferSourceContext *s = ctx->priv; + + if (!s->eof && ff_outlink_get_status(ctx->outputs[0])) + s->eof = 1; + + return s->eof ? AVERROR(EOF) : 0; +} + static av_cold int init_video(AVFilterContext *ctx) { BufferSourceContext *c = ctx->priv; diff --git a/libavfilter/buffersrc.h b/libavfilter/buffersrc.h index 6f3344f44..4bc8fba14 100644 --- a/libavfilter/buffersrc.h +++ b/libavfilter/buffersrc.h @@ -208,6 +208,14 @@ int av_buffersrc_add_frame_flags(AVFilterContext *buffer_src, */ int av_buffersrc_close(AVFilterContext *ctx, int64_t pts, unsigned flags); +/** + * Returns 0 or a negative AVERROR code. Currently, this will only ever + * return AVERROR(EOF), to indicate that the buffer source has been closed, + * either as a result of av_buffersrc_close(), or because the downstream + * filter is no longer accepting new data. + */ +int av_buffersrc_get_status(AVFilterContext *ctx); + /** * @} */ diff --git a/libavfilter/convolution.h b/libavfilter/convolution.h index 1196c1fcd..d664c990a 100644 --- a/libavfilter/convolution.h +++ b/libavfilter/convolution.h @@ -21,6 +21,7 @@ #ifndef AVFILTER_CONVOLUTION_H #define AVFILTER_CONVOLUTION_H #include "avfilter.h" +#include "libavutil/internal.h" #include "libavutil/intreadwrite.h" enum MatrixMode { @@ -71,11 +72,8 @@ static void setup_3x3(int radius, const uint8_t *c[], const uint8_t *src, int st int i; for (i = 0; i < 9; i++) { - int xoff = FFABS(x + ((i % 3) - 1)); - int yoff = FFABS(y + (i / 3) - 1); - - xoff = xoff >= w ? 2 * w - 1 - xoff : xoff; - yoff = yoff >= h ? 2 * h - 1 - yoff : yoff; + int xoff = avpriv_mirror(x + (i % 3) - 1, w - 1); + int yoff = avpriv_mirror(y + (i / 3) - 1, h - 1); c[i] = src + xoff * bpc + yoff * stride; } diff --git a/libavfilter/dnn/dnn_interface.c b/libavfilter/dnn/dnn_interface.c index bb477348d..c4e410756 100644 --- a/libavfilter/dnn/dnn_interface.c +++ b/libavfilter/dnn/dnn_interface.c @@ -137,4 +137,3 @@ const AVClass *ff_dnn_child_class_iterate_with_mask(void **iter, uint32_t backen return NULL; } - diff --git a/libavfilter/framesync.c b/libavfilter/framesync.c index 0d5779f83..846d1c7e5 100644 --- a/libavfilter/framesync.c +++ b/libavfilter/framesync.c @@ -248,7 +248,7 @@ static void framesync_inject_frame(FFFrameSync *fs, unsigned in, AVFrame *frame) av_assert0(!fs->in[in].have_next); av_assert0(frame); - pts = av_rescale_q(frame->pts, fs->in[in].time_base, fs->time_base); + pts = av_rescale_q_rnd(frame->pts, fs->in[in].time_base, fs->time_base, AV_ROUND_NEAR_INF | AV_ROUND_PASS_MINMAX); frame->pts = pts; fs->in[in].frame_next = frame; fs->in[in].pts_next = pts; diff --git a/libavfilter/perlin.c b/libavfilter/perlin.c index ffad8c1e4..ac8272df1 100644 --- a/libavfilter/perlin.c +++ b/libavfilter/perlin.c @@ -221,4 +221,3 @@ double ff_perlin_get(FFPerlin *perlin, double x, double y, double z) return total / max_value; } - diff --git a/libavfilter/qp_table.c b/libavfilter/qp_table.c index 8137dc019..a30e1a919 100644 --- a/libavfilter/qp_table.c +++ b/libavfilter/qp_table.c @@ -66,4 +66,3 @@ int ff_qp_table_extract(AVFrame *frame, int8_t **table, int *table_w, int *table return 0; } - diff --git a/libavfilter/scale_eval.c b/libavfilter/scale_eval.c index dc8d522b1..f2741e1aa 100644 --- a/libavfilter/scale_eval.c +++ b/libavfilter/scale_eval.c @@ -83,18 +83,27 @@ int ff_scale_eval_dimensions(void *log_ctx, av_expr_parse_and_eval(&res, (expr = w_expr), var_names, var_values, NULL, NULL, NULL, NULL, NULL, 0, log_ctx); - eval_w = var_values[VAR_OUT_W] = var_values[VAR_OW] = (int) res == 0 ? inlink->w : (int) res; + var_values[VAR_OUT_W] = var_values[VAR_OW] = res == 0 ? inlink->w : trunc(res); if ((ret = av_expr_parse_and_eval(&res, (expr = h_expr), var_names, var_values, NULL, NULL, NULL, NULL, NULL, 0, log_ctx)) < 0) goto fail; + if (!(res >= INT32_MIN && res <= INT32_MAX)) { + ret = AVERROR(EINVAL); + goto fail; + } + eval_h = var_values[VAR_OUT_H] = var_values[VAR_OH] = (int) res == 0 ? inlink->h : (int) res; /* evaluate again the width, as it may depend on the output height */ if ((ret = av_expr_parse_and_eval(&res, (expr = w_expr), var_names, var_values, NULL, NULL, NULL, NULL, NULL, 0, log_ctx)) < 0) goto fail; + if (!(res >= INT32_MIN && res <= INT32_MAX)) { + ret = AVERROR(EINVAL); + goto fail; + } eval_w = (int) res == 0 ? inlink->w : (int) res; *ret_w = eval_w; @@ -115,7 +124,7 @@ int ff_scale_adjust_dimensions(AVFilterLink *inlink, int force_original_aspect_ratio, int force_divisible_by) { int64_t w, h; - int factor_w, factor_h; + int64_t factor_w, factor_h; w = *ret_w; h = *ret_h; diff --git a/libavfilter/scene_sad.c b/libavfilter/scene_sad.c index caf911eb5..91c4e8934 100644 --- a/libavfilter/scene_sad.c +++ b/libavfilter/scene_sad.c @@ -70,4 +70,3 @@ ff_scene_sad_fn ff_scene_sad_get_fn(int depth) } return sad; } - diff --git a/libavfilter/stack_internal.h b/libavfilter/stack_internal.h index ace888615..b4f9b9222 100644 --- a/libavfilter/stack_internal.h +++ b/libavfilter/stack_internal.h @@ -19,6 +19,10 @@ #ifndef AVFILTER_STACK_INTERNAL_H #define AVFILTER_STACK_INTERNAL_H +#ifdef HWContext + +#include "libavfilter/framesync.h" + enum { STACK_H = 0, STACK_V = 1, @@ -57,4 +61,6 @@ static int stack_init(AVFilterContext *avctx); static av_cold void stack_uninit(AVFilterContext *avctx); static int stack_activate(AVFilterContext *avctx); +#endif + #endif /* AVFILTER_STACK_INTERNAL_H */ diff --git a/libavfilter/textutils.c b/libavfilter/textutils.c index e6b5239b2..568e35098 100644 --- a/libavfilter/textutils.c +++ b/libavfilter/textutils.c @@ -380,4 +380,3 @@ int ff_load_textfile(void *log_ctx, const char *textfile, return 0; } - diff --git a/libavfilter/version.h b/libavfilter/version.h index 4d8f28e51..523a7fe0a 100644 --- a/libavfilter/version.h +++ b/libavfilter/version.h @@ -31,7 +31,7 @@ #include "version_major.h" -#define LIBAVFILTER_VERSION_MINOR 4 +#define LIBAVFILTER_VERSION_MINOR 5 #define LIBAVFILTER_VERSION_MICRO 100 diff --git a/libavfilter/vf_bwdif.c b/libavfilter/vf_bwdif.c index d41a25f8e..10e7130c4 100644 --- a/libavfilter/vf_bwdif.c +++ b/libavfilter/vf_bwdif.c @@ -77,11 +77,20 @@ static int filter_slice(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs) uint8_t *next = &yadif->next->data[td->plane][y * linesize]; uint8_t *dst = &td->frame->data[td->plane][y * td->frame->linesize[td->plane]]; if (yadif->current_field == YADIF_FIELD_END) { - s->dsp.filter_intra(dst, cur, td->w, (y + df) < td->h ? refs : -refs, - y > (df - 1) ? -refs : refs, - (y + 3*df) < td->h ? 3 * refs : -refs, - y > (3*df - 1) ? -3 * refs : refs, - td->parity ^ td->tff, clip_max); + if ((y < 3) || ((y + 3) >= td->h)) { + s->dsp.filter_edge(dst, prev, cur, next, td->w, + (y + df) < td->h ? refs : -refs, + y > (df - 1) ? -refs : refs, + refs << 1, -(refs << 1), + td->parity ^ td->tff, clip_max, + (y < 2) || ((y + 3) > td->h) ? 0 : 1); + } else { + s->dsp.filter_intra(dst, cur, td->w, (y + df) < td->h ? refs : -refs, + y > (df - 1) ? -refs : refs, + (y + 3*df) < td->h ? 3 * refs : -refs, + y > (3*df - 1) ? -3 * refs : refs, + td->parity ^ td->tff, clip_max); + } } else if ((y < 4) || ((y + 5) > td->h)) { s->dsp.filter_edge(dst, prev, cur, next, td->w, (y + df) < td->h ? refs : -refs, diff --git a/libavfilter/vf_codecview.c b/libavfilter/vf_codecview.c index b7396f666..33d1f1293 100644 --- a/libavfilter/vf_codecview.c +++ b/libavfilter/vf_codecview.c @@ -266,9 +266,22 @@ static int filter_frame(AVFilterLink *inlink, AVFrame *frame) if (par->nb_blocks) { for (int block_idx = 0; block_idx < par->nb_blocks; block_idx++) { AVVideoBlockParams *b = av_video_enc_params_block(par, block_idx); - uint8_t *buf = frame->data[0] + b->src_y * stride; - draw_block_rectangle(buf, b->src_x, b->src_y, b->w, b->h, stride, 100); + int64_t x0 = b->src_x; + int64_t y0 = b->src_y; + int64_t x1 = x0 + b->w; + int64_t y1 = y0 + b->h; + + x0 = FFMAX(x0, 0); + y0 = FFMAX(y0, 0); + x1 = FFMIN(x1, frame->width); + y1 = FFMIN(y1, frame->height); + + if (x1 <= x0 || y1 <= y0) + continue; + + uint8_t *buf = frame->data[0] + y0 * stride; + draw_block_rectangle(buf, x0, y0, x1-x0, y1-y0, stride, 100); } } } diff --git a/libavfilter/vf_convolution.c b/libavfilter/vf_convolution.c index aacfe0add..0f265888a 100644 --- a/libavfilter/vf_convolution.c +++ b/libavfilter/vf_convolution.c @@ -520,11 +520,8 @@ static void setup_5x5(int radius, const uint8_t *c[], const uint8_t *src, int st int i; for (i = 0; i < 25; i++) { - int xoff = FFABS(x + ((i % 5) - 2)); - int yoff = FFABS(y + (i / 5) - 2); - - xoff = xoff >= w ? 2 * w - 1 - xoff : xoff; - yoff = yoff >= h ? 2 * h - 1 - yoff : yoff; + int xoff = avpriv_mirror(x + (i % 5) - 2, w - 1); + int yoff = avpriv_mirror(y + (i / 5) - 2, h - 1); c[i] = src + xoff * bpc + yoff * stride; } @@ -536,11 +533,8 @@ static void setup_7x7(int radius, const uint8_t *c[], const uint8_t *src, int st int i; for (i = 0; i < 49; i++) { - int xoff = FFABS(x + ((i % 7) - 3)); - int yoff = FFABS(y + (i / 7) - 3); - - xoff = xoff >= w ? 2 * w - 1 - xoff : xoff; - yoff = yoff >= h ? 2 * h - 1 - yoff : yoff; + int xoff = avpriv_mirror(x + (i % 7) - 3, w - 1); + int yoff = avpriv_mirror(y + (i / 7) - 3, h - 1); c[i] = src + xoff * bpc + yoff * stride; } @@ -552,9 +546,7 @@ static void setup_row(int radius, const uint8_t *c[], const uint8_t *src, int st int i; for (i = 0; i < radius * 2 + 1; i++) { - int xoff = FFABS(x + i - radius); - - xoff = xoff >= w ? 2 * w - 1 - xoff : xoff; + int xoff = avpriv_mirror(x + i - radius, w - 1); c[i] = src + xoff * bpc + y * stride; } @@ -566,9 +558,7 @@ static void setup_column(int radius, const uint8_t *c[], const uint8_t *src, int int i; for (i = 0; i < radius * 2 + 1; i++) { - int xoff = FFABS(x + i - radius); - - xoff = xoff >= h ? 2 * h - 1 - xoff : xoff; + int xoff = avpriv_mirror(x + i - radius, h - 1); c[i] = src + y * bpc + xoff * stride; } @@ -614,10 +604,12 @@ static int filter_slice(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs) continue; } for (y = slice_start; y < slice_end; y += step) { - const int xoff = mode == MATRIX_COLUMN ? (y - slice_start) * bpc : radius * bpc; - const int yoff = mode == MATRIX_COLUMN ? radius * dstride : 0; + const int left = FFMIN(radius, sizew); + const int right = FFMAX(left, sizew - radius); + const int xoff = mode == MATRIX_COLUMN ? (y - slice_start) * bpc : left * bpc; + const int yoff = mode == MATRIX_COLUMN ? left * dstride : 0; - for (x = 0; x < radius; x++) { + for (x = 0; x < left; x++) { const int xoff = mode == MATRIX_COLUMN ? (y - slice_start) * bpc : x * bpc; const int yoff = mode == MATRIX_COLUMN ? x * dstride : 0; @@ -626,11 +618,11 @@ static int filter_slice(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs) bias, matrix, c, s->max, radius, dstride, stride, slice_end - step); } - s->setup[plane](radius, c, src, stride, radius, width, y, height, bpc); - s->filter[plane](dst + yoff + xoff, sizew - 2 * radius, + s->setup[plane](radius, c, src, stride, left, width, y, height, bpc); + s->filter[plane](dst + yoff + xoff, right - left, rdiv, bias, matrix, c, s->max, radius, dstride, stride, slice_end - step); - for (x = sizew - radius; x < sizew; x++) { + for (x = right; x < sizew; x++) { const int xoff = mode == MATRIX_COLUMN ? (y - slice_start) * bpc : x * bpc; const int yoff = mode == MATRIX_COLUMN ? x * dstride : 0; diff --git a/libavfilter/vf_drawtext.c b/libavfilter/vf_drawtext.c index dccc534bb..f4cc8179d 100644 --- a/libavfilter/vf_drawtext.c +++ b/libavfilter/vf_drawtext.c @@ -1434,8 +1434,13 @@ continue_on_failed: } s->line_count = line_count; - s->lines = av_mallocz(line_count * sizeof(TextLine)); - s->tab_clusters = av_mallocz(s->tab_count * sizeof(uint32_t)); + s->lines = av_calloc(line_count, sizeof(TextLine)); + s->tab_clusters = av_calloc(s->tab_count, sizeof(uint32_t)); + if ((line_count > 0 && !s->lines) || + (s->tab_count > 0 && !s->tab_clusters)) { + ret = AVERROR(ENOMEM); + goto done; + } for (i = 0; i < s->tab_count; ++i) { s->tab_clusters[i] = -1; } @@ -1451,13 +1456,14 @@ continue_on_failed: s->tab_clusters[tab_idx++] = i; *p = ' '; } + size_t len = p - start; GET_UTF8(code, *p ? *p++ : 0, code = 0xfffd; goto continue_on_failed2;); continue_on_failed2: if (ff_is_newline(code) || code == 0) { TextLine *cur_line = &s->lines[line_count]; HarfbuzzData *hb = &cur_line->hb_data; cur_line->cluster_offset = line_offset; - ret = shape_text_hb(s, hb, start, p - start); + ret = shape_text_hb(s, hb, start, len); if (ret != 0) { goto done; } diff --git a/libavfilter/vf_find_rect.c b/libavfilter/vf_find_rect.c index 1b11fbbb9..a45fbf057 100644 --- a/libavfilter/vf_find_rect.c +++ b/libavfilter/vf_find_rect.c @@ -53,8 +53,8 @@ static const AVOption find_rect_options[] = { { "mipmaps", "set mipmaps", OFFSET(mipmaps), AV_OPT_TYPE_INT, {.i64 = 3}, 1, MAX_MIPMAPS, FLAGS }, { "xmin", "", OFFSET(xmin), AV_OPT_TYPE_INT, {.i64 = 0}, 0, INT_MAX, FLAGS }, { "ymin", "", OFFSET(ymin), AV_OPT_TYPE_INT, {.i64 = 0}, 0, INT_MAX, FLAGS }, - { "xmax", "", OFFSET(xmax), AV_OPT_TYPE_INT, {.i64 = 0}, 0, INT_MAX, FLAGS }, - { "ymax", "", OFFSET(ymax), AV_OPT_TYPE_INT, {.i64 = 0}, 0, INT_MAX, FLAGS }, + { "xmax", "", OFFSET(xmax), AV_OPT_TYPE_INT, {.i64 = INT_MAX}, 0, INT_MAX, FLAGS }, + { "ymax", "", OFFSET(ymax), AV_OPT_TYPE_INT, {.i64 = INT_MAX}, 0, INT_MAX, FLAGS }, { "discard", "", OFFSET(discard), AV_OPT_TYPE_BOOL, {.i64 = 0}, 0, 1, FLAGS }, { NULL } }; @@ -80,8 +80,10 @@ static AVFrame *downscale(AVFrame *in) src = in ->data[0]; dst = frame->data[0]; - for(y = 0; y < frame->height; y++) { - for(x = 0; x < frame->width; x++) { + int w2 = in->width/2; + int h2 = in->height/2; + for(y = 0; y < h2; y++) { + for(x = 0; x < w2; x++) { dst[x] = ( src[2*x+0] + src[2*x+1] + src[2*x+0 + in->linesize[0]] @@ -91,6 +93,22 @@ static AVFrame *downscale(AVFrame *in) src += 2*in->linesize[0]; dst += frame->linesize[0]; } + src = in ->data[0]; + dst = frame->data[0]; + for(y = 0; y < frame->height; y++) { + int yd = y < h2 ? in->linesize[0] : 0; + x = yd ? w2 : 0; + for(; x < frame->width; x++) { + dst[x] = ( src[2*x+0] + + src[FFMIN(2*x+1, w2)] + + src[2*x+0 + yd] + + src[FFMIN(2*x+1, w2) + yd] + + 2) >> 2; + } + src += 2*in->linesize[0]; + dst += frame->linesize[0]; + } + return frame; } @@ -132,19 +150,6 @@ static float compare(const AVFrame *haystack, const AVFrame *obj, int offx, int return 1 - fabs(c); } -static int config_input(AVFilterLink *inlink) -{ - AVFilterContext *ctx = inlink->dst; - FOCContext *foc = ctx->priv; - - if (foc->xmax <= 0) - foc->xmax = inlink->w - foc->obj_frame->width; - if (foc->ymax <= 0) - foc->ymax = inlink->h - foc->obj_frame->height; - - return 0; -} - static float search(FOCContext *foc, int pass, int maxpass, int xmin, int xmax, int ymin, int ymax, int *best_x, int *best_y, float best_score) { int x, y; @@ -181,19 +186,24 @@ static int filter_frame(AVFilterLink *inlink, AVFrame *in) int i; char buf[32]; + int xmin = FFMAX(foc->xmin, 0); + int ymin = FFMAX(foc->ymin, 0); + int xmax = FFMIN(foc->xmax, inlink->w - foc->obj_frame->width ); + int ymax = FFMIN(foc->ymax, inlink->h - foc->obj_frame->height); + foc->haystack_frame[0] = av_frame_clone(in); for (i=1; imipmaps; i++) { foc->haystack_frame[i] = downscale(foc->haystack_frame[i-1]); } best_score = search(foc, 0, 0, - FFMAX(foc->xmin, foc->last_x - 8), - FFMIN(foc->xmax, foc->last_x + 8), - FFMAX(foc->ymin, foc->last_y - 8), - FFMIN(foc->ymax, foc->last_y + 8), + FFMAX(xmin, foc->last_x - 8), + FFMIN(xmax, foc->last_x + 8), + FFMAX(ymin, foc->last_y - 8), + FFMIN(ymax, foc->last_y + 8), &best_x, &best_y, 2.0); - best_score = search(foc, 0, foc->mipmaps - 1, foc->xmin, foc->xmax, foc->ymin, foc->ymax, + best_score = search(foc, 0, foc->mipmaps - 1, xmin, xmax, ymin, ymax, &best_x, &best_y, best_score); for (i=0; iis_packed_rgb = av_pix_fmt_desc_get(inlink->format)->flags & AV_PIX_FMT_FLAG_RGB; kerndeint->vsub = desc->log2_chroma_h; + if (AV_CEIL_RSHIFT(inlink->h, kerndeint->vsub) < 4) { + av_log(inlink->dst, AV_LOG_ERROR, + "Input height %d is too small; minimum chroma plane height is 4\n", + inlink->h); + return AVERROR(EINVAL); + } ret = av_image_alloc(kerndeint->tmp_data, kerndeint->tmp_linesize, inlink->w, inlink->h, inlink->format, 16); diff --git a/libavfilter/vf_lcevc.c b/libavfilter/vf_lcevc.c index b83dc94e0..318b14437 100644 --- a/libavfilter/vf_lcevc.c +++ b/libavfilter/vf_lcevc.c @@ -139,7 +139,11 @@ static int send_frame(AVFilterLink *inlink, AVFrame *in) return ret; if (sd) { +#ifdef LCEVC_DEC_VERSION_MAJOR + res = LCEVC_SendDecoderEnhancementData(lcevc->decoder, in->pts, sd->data, sd->size); +#else res = LCEVC_SendDecoderEnhancementData(lcevc->decoder, in->pts, 0, sd->data, sd->size); +#endif if (res == LCEVC_Again) return AVERROR(EAGAIN); else if (res != LCEVC_Success) { @@ -148,7 +152,18 @@ static int send_frame(AVFilterLink *inlink, AVFrame *in) } } + res = LCEVC_SetPictureUserData(lcevc->decoder, picture, in); + if (res != LCEVC_Success) { + av_log(ctx, AV_LOG_ERROR, "LCEVC_SetPictureUserData failed\n"); + LCEVC_FreePicture(lcevc->decoder, picture); + return AVERROR_EXTERNAL; + } + +#ifdef LCEVC_DEC_VERSION_MAJOR + res = LCEVC_SendDecoderBase(lcevc->decoder, in->pts, picture, -1, in); +#else res = LCEVC_SendDecoderBase(lcevc->decoder, in->pts, 0, picture, -1, in); +#endif if (res != LCEVC_Success) { av_log(ctx, AV_LOG_ERROR, "LCEVC_SendDecoderBase failed\n"); LCEVC_FreePicture(lcevc->decoder, picture); @@ -215,8 +230,6 @@ static int generate_output(AVFilterLink *inlink, AVFrame *out) av_frame_copy_props(out, (AVFrame *)info.baseUserData); av_frame_remove_side_data(out, AV_FRAME_DATA_LCEVC); - av_frame_free((AVFrame **)&info.baseUserData); - res = LCEVC_GetPictureDesc(lcevc->decoder, picture, &desc); LCEVC_FreePicture(lcevc->decoder, picture); @@ -284,8 +297,12 @@ static void flush_bases(AVFilterContext *ctx) LCEVCContext *lcevc = ctx->priv; LCEVC_PictureHandle picture; - while (LCEVC_ReceiveDecoderBase(lcevc->decoder, &picture) == LCEVC_Success) + while (LCEVC_ReceiveDecoderBase(lcevc->decoder, &picture) == LCEVC_Success) { + AVFrame *base = NULL; + LCEVC_GetPictureUserData(lcevc->decoder, picture, (void **)&base); LCEVC_FreePicture(lcevc->decoder, picture); + av_frame_free(&base); + } } static int activate(AVFilterContext *ctx) @@ -399,6 +416,8 @@ static av_cold void uninit(AVFilterContext *ctx) { LCEVCContext *lcevc = ctx->priv; + LCEVC_FlushDecoder(lcevc->decoder); + flush_bases(ctx); LCEVC_DestroyDecoder(lcevc->decoder); } diff --git a/libavfilter/vf_libopencv.c b/libavfilter/vf_libopencv.c index 0250a5483..254d9883b 100644 --- a/libavfilter/vf_libopencv.c +++ b/libavfilter/vf_libopencv.c @@ -210,7 +210,7 @@ static int parse_iplconvkernel(IplConvKernel **kernel, char *buf, void *log_ctx) int cols = 0, rows = 0, anchor_x = 0, anchor_y = 0, shape = CV_SHAPE_RECT; int *values = NULL, ret = 0; - sscanf(buf, "%dx%d+%dx%d/%32[^=]=%127s", &cols, &rows, &anchor_x, &anchor_y, shape_str, shape_filename); + sscanf(buf, "%dx%d+%dx%d/%31[^=]=%127s", &cols, &rows, &anchor_x, &anchor_y, shape_str, shape_filename); if (!strcmp(shape_str, "rect" )) shape = CV_SHAPE_RECT; else if (!strcmp(shape_str, "cross" )) shape = CV_SHAPE_CROSS; diff --git a/libavfilter/vf_neighbor_opencl.c b/libavfilter/vf_neighbor_opencl.c index d8238a138..f9fc8da30 100644 --- a/libavfilter/vf_neighbor_opencl.c +++ b/libavfilter/vf_neighbor_opencl.c @@ -69,6 +69,9 @@ static int neighbor_opencl_init(AVFilterContext *avctx) kernel_name = "erosion_global"; } else if (!strcmp(avctx->filter->name, "dilation_opencl")){ kernel_name = "dilation_global"; + } else { + err = AVERROR_BUG; + goto fail; } ctx->kernel = clCreateKernel(ctx->ocf.program, kernel_name, &cle); CL_FAIL_ON_ERROR(AVERROR(EIO), "Failed to create " diff --git a/libavfilter/vf_overlay_cuda.cu b/libavfilter/vf_overlay_cuda.cu index 43ec36c2e..9f1db0e9a 100644 --- a/libavfilter/vf_overlay_cuda.cu +++ b/libavfilter/vf_overlay_cuda.cu @@ -51,4 +51,3 @@ __global__ void Overlay_Cuda( } } - diff --git a/libavfilter/vf_quirc.c b/libavfilter/vf_quirc.c index afd172fa3..2aee81b4d 100644 --- a/libavfilter/vf_quirc.c +++ b/libavfilter/vf_quirc.c @@ -182,4 +182,3 @@ const AVFilter ff_vf_quirc = { .flags = AVFILTER_FLAG_SUPPORT_TIMELINE_GENERIC | AVFILTER_FLAG_METADATA_ONLY, }; - diff --git a/libavfilter/vf_scale.c b/libavfilter/vf_scale.c index 3319428d9..ac6a9a0c9 100644 --- a/libavfilter/vf_scale.c +++ b/libavfilter/vf_scale.c @@ -693,8 +693,8 @@ static int config_props(AVFilterLink *outlink) if (outlink->w > INT_MAX || outlink->h > INT_MAX || - (outlink->h * inlink->w) > INT_MAX || - (outlink->w * inlink->h) > INT_MAX) + (outlink->h * (uint64_t)inlink->w) > INT_MAX || + (outlink->w * (uint64_t)inlink->h) > INT_MAX) av_log(ctx, AV_LOG_ERROR, "Rescaled value for width or height is too big.\n"); /* TODO: make algorithm configurable */ @@ -1119,7 +1119,7 @@ FF_ENABLE_DEPRECATION_WARNINGS goto err; av_assert0(out); - out->pts = av_rescale_q(fs->pts, fs->time_base, outlink->time_base); + out->pts = av_rescale_q_rnd(fs->pts, fs->time_base, outlink->time_base, AV_ROUND_NEAR_INF | AV_ROUND_PASS_MINMAX); return ff_filter_frame(outlink, out); err: diff --git a/libavfilter/vf_ssim360.c b/libavfilter/vf_ssim360.c index 42632bcd8..ba0e8ba07 100644 --- a/libavfilter/vf_ssim360.c +++ b/libavfilter/vf_ssim360.c @@ -1034,10 +1034,16 @@ generate_eye_tape_map(SSIM360Context *s, float x_range = end_x - start_x; // Ensure tape length is a multiple of 4, for full SSIM block coverage - int tape_length = s->tape_length[plane] = ((int)ROUNDED_DIV(x_range, 4)) << 2; + float tape_length_f = ROUNDED_DIV(x_range, 4); + int tape_length; - s->ref_tape_map[plane][eye] = av_malloc_array(tape_length * 8, sizeof(BilinearMap)); - s->main_tape_map[plane][eye] = av_malloc_array(tape_length * 8, sizeof(BilinearMap)); + if (!(tape_length_f > 0.f) || tape_length_f > INT_MAX / 4.0f) + return AVERROR(EINVAL); + + tape_length = s->tape_length[plane] = (int)tape_length_f << 2; + + s->ref_tape_map[plane][eye] = av_malloc_array(tape_length, 8 * sizeof(BilinearMap)); + s->main_tape_map[plane][eye] = av_malloc_array(tape_length, 8 * sizeof(BilinearMap)); if (!s->ref_tape_map[plane][eye] || !s->main_tape_map[plane][eye]) return AVERROR(ENOMEM); diff --git a/libavfilter/vf_stack.c b/libavfilter/vf_stack.c index 832804864..7b62cb76b 100644 --- a/libavfilter/vf_stack.c +++ b/libavfilter/vf_stack.c @@ -230,6 +230,8 @@ static int config_output(AVFilterLink *outlink) item->y[1] = item->y[2] = AV_CEIL_RSHIFT(height, s->desc->log2_chroma_h); item->y[0] = item->y[3] = height; + if (height > INT_MAX - ctx->inputs[i]->h) + return AVERROR(EINVAL); height += ctx->inputs[i]->h; } } @@ -255,6 +257,8 @@ static int config_output(AVFilterLink *outlink) return ret; } + if (width > INT_MAX - ctx->inputs[i]->w) + return AVERROR(EINVAL); width += ctx->inputs[i]->w; } } @@ -290,8 +294,13 @@ static int config_output(AVFilterLink *outlink) item->y[1] = item->y[2] = AV_CEIL_RSHIFT(inh, s->desc->log2_chroma_h); item->y[0] = item->y[3] = inh; + + if (inw > INT_MAX - ctx->inputs[k]->w) + return AVERROR(EINVAL); inw += ctx->inputs[k]->w; } + if (height > INT_MAX - row_height) + return AVERROR(EINVAL); height += row_height; if (!i) width = inw; @@ -343,26 +352,41 @@ static int config_output(AVFilterLink *outlink) if (size == i || size < 0 || size >= s->nb_inputs) return AVERROR(EINVAL); - if (!j) + if (!j) { + if (inw > INT_MAX - ctx->inputs[size]->w) + return AVERROR(EINVAL); inw += ctx->inputs[size]->w; - else + } else { + if (inh > INT_MAX - ctx->inputs[size]->w) + return AVERROR(EINVAL); inh += ctx->inputs[size]->w; + } } else if (sscanf(arg3, "h%d", &size) == 1) { if (size == i || size < 0 || size >= s->nb_inputs) return AVERROR(EINVAL); - if (!j) + if (!j) { + if (inw > INT_MAX - ctx->inputs[size]->h) + return AVERROR(EINVAL); inw += ctx->inputs[size]->h; - else + } else { + if (inh > INT_MAX - ctx->inputs[size]->h) + return AVERROR(EINVAL); inh += ctx->inputs[size]->h; + } } else if (sscanf(arg3, "%d", &size) == 1) { if (size < 0) return AVERROR(EINVAL); - if (!j) + if (!j) { + if (inw > INT_MAX - size) + return AVERROR(EINVAL); inw += size; - else + } else { + if (inh > INT_MAX - size) + return AVERROR(EINVAL); inh += size; + } } else { return AVERROR(EINVAL); } @@ -376,6 +400,8 @@ static int config_output(AVFilterLink *outlink) item->y[1] = item->y[2] = AV_CEIL_RSHIFT(inh, s->desc->log2_chroma_h); item->y[0] = item->y[3] = inh; + if (inlink->w > INT_MAX - inw || inlink->h > INT_MAX - inh) + return AVERROR(EINVAL); width = FFMAX(width, inlink->w + inw); height = FFMAX(height, inlink->h + inh); } diff --git a/libavfilter/vf_v360.c b/libavfilter/vf_v360.c index 4ba389e33..3238bae6b 100644 --- a/libavfilter/vf_v360.c +++ b/libavfilter/vf_v360.c @@ -288,7 +288,7 @@ static int remap##ws##_##bits##bit_slice(AVFilterContext *ctx, void *arg, int jo \ av_assert1(s->nb_planes <= AV_VIDEO_MAX_PLANES); \ \ - for (int stereo = 0; stereo < 1 + s->out_stereo > STEREO_2D; stereo++) { \ + for (int stereo = 0; stereo < 1 + (s->out_stereo > STEREO_2D); stereo++) { \ for (int plane = 0; plane < s->nb_planes; plane++) { \ const unsigned map = s->map[plane]; \ const int in_linesize = in->linesize[plane]; \ diff --git a/libavfilter/vf_zscale.c b/libavfilter/vf_zscale.c index afd22ce6c..2f84715bc 100644 --- a/libavfilter/vf_zscale.c +++ b/libavfilter/vf_zscale.c @@ -264,7 +264,7 @@ static int config_props(AVFilterLink *outlink) double var_values[VARS_NB], res; char *expr; int ret; - int factor_w, factor_h; + int64_t factor_w, factor_h; var_values[VAR_IN_W] = var_values[VAR_IW] = inlink->w; var_values[VAR_IN_H] = var_values[VAR_IH] = inlink->h; @@ -283,17 +283,26 @@ static int config_props(AVFilterLink *outlink) av_expr_parse_and_eval(&res, (expr = s->w_expr), var_names, var_values, NULL, NULL, NULL, NULL, NULL, 0, ctx); - s->w = var_values[VAR_OUT_W] = var_values[VAR_OW] = res; + var_values[VAR_OUT_W] = var_values[VAR_OW] = trunc(res); if ((ret = av_expr_parse_and_eval(&res, (expr = s->h_expr), var_names, var_values, NULL, NULL, NULL, NULL, NULL, 0, ctx)) < 0) goto fail; + if (!(res >= INT32_MIN && res <= INT32_MAX)) { + ret = AVERROR(EINVAL); + goto fail; + } + s->h = var_values[VAR_OUT_H] = var_values[VAR_OH] = res; /* evaluate again the width, as it may depend on the output height */ if ((ret = av_expr_parse_and_eval(&res, (expr = s->w_expr), var_names, var_values, NULL, NULL, NULL, NULL, NULL, 0, ctx)) < 0) goto fail; + if (!(res >= INT32_MIN && res <= INT32_MAX)) { + ret = AVERROR(EINVAL); + goto fail; + } s->w = res; w = s->w; diff --git a/libavformat/avidec.c b/libavformat/avidec.c index 81a0ae31b..281311cc6 100644 --- a/libavformat/avidec.c +++ b/libavformat/avidec.c @@ -556,9 +556,11 @@ static int avi_read_header(AVFormatContext *s) avi->movi_end = avi->fsize; av_log(s, AV_LOG_TRACE, "movi end=%"PRIx64"\n", avi->movi_end); goto end_of_header; - } else if (tag1 == MKTAG('I', 'N', 'F', 'O')) + } else if (tag1 == MKTAG('I', 'N', 'F', 'O')) { + if (size < 4) + return AVERROR_INVALIDDATA; ff_read_riff_info(s, size - 4); - else if (tag1 == MKTAG('n', 'c', 'd', 't')) + } else if (tag1 == MKTAG('n', 'c', 'd', 't')) avi_read_nikon(s, list_end); break; @@ -1828,6 +1830,10 @@ static int avi_load_index(AVFormatContext *s) avi->index_loaded=2; ret = 0; }else if (tag == MKTAG('L', 'I', 'S', 'T')) { + if (size < 4) { + av_log(s, AV_LOG_WARNING, "Invalid size (%u) LIST in index\n", size); + break; + } uint32_t tag1 = avio_rl32(pb); if (tag1 == MKTAG('I', 'N', 'F', 'O')) diff --git a/libavformat/cafdec.c b/libavformat/cafdec.c index 5d7dbe8f4..2198acaa7 100644 --- a/libavformat/cafdec.c +++ b/libavformat/cafdec.c @@ -288,6 +288,10 @@ static void read_info_chunk(AVFormatContext *s, int64_t size) AVIOContext *pb = s->pb; unsigned int i; unsigned int nb_entries = avio_rb32(pb); + + if (3LL * nb_entries > size) + return; + for (i = 0; i < nb_entries && !avio_feof(pb); i++) { char key[32]; char value[1024]; @@ -501,6 +505,8 @@ static int read_seek(AVFormatContext *s, int stream_index, frame_cnt = caf->frames_per_packet * packet_cnt; } else if (sti->nb_index_entries) { packet_cnt = av_index_search_timestamp(st, timestamp, flags); + if (packet_cnt < 0) + return -1; frame_cnt = sti->index_entries[packet_cnt].timestamp; pos = sti->index_entries[packet_cnt].pos; } else { diff --git a/libavformat/concat.c b/libavformat/concat.c index e1d57de55..31aa1741d 100644 --- a/libavformat/concat.c +++ b/libavformat/concat.c @@ -113,6 +113,12 @@ static av_cold int concat_open(URLContext *h, const char *uri, int flags) break; } + if (total_size > INT64_MAX - size) { + ffurl_close(uc); + err = AVERROR_INVALIDDATA; + break; + } + /* assembling */ nodes[i].uc = uc; nodes[i].size = size; @@ -282,6 +288,12 @@ static av_cold int concatf_open(URLContext *h, const char *uri, int flags) break; } + if (total_size > INT64_MAX - size) { + ffurl_close(uc); + err = AVERROR_INVALIDDATA; + break; + } + nodes = av_fast_realloc(data->nodes, &nodes_size, sizeof(*nodes) * len); if (!nodes) { ffurl_close(uc); diff --git a/libavformat/dash.c b/libavformat/dash.c index d7ba8540d..fddfa8234 100644 --- a/libavformat/dash.c +++ b/libavformat/dash.c @@ -152,5 +152,3 @@ void ff_dash_fill_tmpl_params(char *dst, size_t buffer_size, t_cur = t_next; } } - - diff --git a/libavformat/dashdec.c b/libavformat/dashdec.c index 71f5d76c2..c92756505 100644 --- a/libavformat/dashdec.c +++ b/libavformat/dashdec.c @@ -831,6 +831,43 @@ end: } +#define SET_REPRESENTATION_SEQUENCE_BASE_INFO(arg, cnt) { \ + val = get_val_from_nodes_tab((arg), (cnt), "duration"); \ + if (val) { \ + int64_t fragment_duration = (int64_t) strtoll(val, NULL, 10); \ + if (fragment_duration < 0) { \ + av_log(s, AV_LOG_WARNING, "duration invalid, autochanged to 0.\n"); \ + fragment_duration = 0; \ + } \ + rep->fragment_duration = fragment_duration; \ + av_log(s, AV_LOG_TRACE, "rep->fragment_duration = [%"PRId64"]\n", rep->fragment_duration); \ + xmlFree(val); \ + } \ + val = get_val_from_nodes_tab((arg), (cnt), "timescale"); \ + if (val) { \ + int64_t fragment_timescale = (int64_t) strtoll(val, NULL, 10); \ + if (fragment_timescale < 0) { \ + av_log(s, AV_LOG_WARNING, "timescale invalid, autochanged to 0.\n"); \ + fragment_timescale = 0; \ + } \ + rep->fragment_timescale = fragment_timescale; \ + av_log(s, AV_LOG_TRACE, "rep->fragment_timescale = [%"PRId64"]\n", rep->fragment_timescale); \ + xmlFree(val); \ + } \ + val = get_val_from_nodes_tab((arg), (cnt), "startNumber"); \ + if (val) { \ + int64_t start_number = (int64_t) strtoll(val, NULL, 10); \ + if (start_number < 0) { \ + av_log(s, AV_LOG_WARNING, "startNumber invalid, autochanged to 0.\n"); \ + start_number = 0; \ + } \ + rep->start_number = rep->first_seq_no = start_number; \ + av_log(s, AV_LOG_TRACE, "rep->first_seq_no = [%"PRId64"]\n", rep->first_seq_no); \ + xmlFree(val); \ + } \ + } + + static int parse_manifest_representation(AVFormatContext *s, const char *url, xmlNodePtr node, xmlNodePtr adaptionset_node, @@ -945,28 +982,17 @@ static int parse_manifest_representation(AVFormatContext *s, const char *url, } val = get_val_from_nodes_tab(fragment_templates_tab, 4, "presentationTimeOffset"); if (val) { - rep->presentation_timeoffset = (int64_t) strtoll(val, NULL, 10); + int64_t presentation_timeoffset = (int64_t) strtoll(val, NULL, 10); + if (presentation_timeoffset < 0) { + av_log(s, AV_LOG_WARNING, "presentationTimeOffset invalid, autochanged to 0.\n"); + presentation_timeoffset = 0; + } + rep->presentation_timeoffset = presentation_timeoffset; av_log(s, AV_LOG_TRACE, "rep->presentation_timeoffset = [%"PRId64"]\n", rep->presentation_timeoffset); xmlFree(val); } - val = get_val_from_nodes_tab(fragment_templates_tab, 4, "duration"); - if (val) { - rep->fragment_duration = (int64_t) strtoll(val, NULL, 10); - av_log(s, AV_LOG_TRACE, "rep->fragment_duration = [%"PRId64"]\n", rep->fragment_duration); - xmlFree(val); - } - val = get_val_from_nodes_tab(fragment_templates_tab, 4, "timescale"); - if (val) { - rep->fragment_timescale = (int64_t) strtoll(val, NULL, 10); - av_log(s, AV_LOG_TRACE, "rep->fragment_timescale = [%"PRId64"]\n", rep->fragment_timescale); - xmlFree(val); - } - val = get_val_from_nodes_tab(fragment_templates_tab, 4, "startNumber"); - if (val) { - rep->start_number = rep->first_seq_no = (int64_t) strtoll(val, NULL, 10); - av_log(s, AV_LOG_TRACE, "rep->first_seq_no = [%"PRId64"]\n", rep->first_seq_no); - xmlFree(val); - } + + SET_REPRESENTATION_SEQUENCE_BASE_INFO(fragment_templates_tab, 4); if (adaptionset_supplementalproperty_node) { char *scheme_id_uri = xmlGetProp(adaptionset_supplementalproperty_node, "schemeIdUri"); if (scheme_id_uri) { @@ -1023,25 +1049,7 @@ static int parse_manifest_representation(AVFormatContext *s, const char *url, segmentlists_tab[1] = adaptionset_segmentlist_node; segmentlists_tab[2] = period_segmentlist_node; - val = get_val_from_nodes_tab(segmentlists_tab, 3, "duration"); - if (val) { - rep->fragment_duration = (int64_t) strtoll(val, NULL, 10); - av_log(s, AV_LOG_TRACE, "rep->fragment_duration = [%"PRId64"]\n", rep->fragment_duration); - xmlFree(val); - } - val = get_val_from_nodes_tab(segmentlists_tab, 3, "timescale"); - if (val) { - rep->fragment_timescale = (int64_t) strtoll(val, NULL, 10); - av_log(s, AV_LOG_TRACE, "rep->fragment_timescale = [%"PRId64"]\n", rep->fragment_timescale); - xmlFree(val); - } - val = get_val_from_nodes_tab(segmentlists_tab, 3, "startNumber"); - if (val) { - rep->start_number = rep->first_seq_no = (int64_t) strtoll(val, NULL, 10); - av_log(s, AV_LOG_TRACE, "rep->first_seq_no = [%"PRId64"]\n", rep->first_seq_no); - xmlFree(val); - } - + SET_REPRESENTATION_SEQUENCE_BASE_INFO(segmentlists_tab, 3) fragmenturl_node = xmlFirstElementChild(representation_segmentlist_node); while (fragmenturl_node) { ret = parse_manifest_segmenturlnode(s, rep, fragmenturl_node, diff --git a/libavformat/demux.c b/libavformat/demux.c index 279620923..e2c5e5d87 100644 --- a/libavformat/demux.c +++ b/libavformat/demux.c @@ -184,6 +184,8 @@ static int init_input(AVFormatContext *s, const char *filename, s, 0, s->format_probesize); } +static int codec_close(FFStream *sti); + static int update_stream_avctx(AVFormatContext *s) { int ret; @@ -194,6 +196,14 @@ static int update_stream_avctx(AVFormatContext *s) if (!sti->need_context_update) continue; + if (avcodec_is_open(sti->avctx)) { + av_log(s, AV_LOG_DEBUG, "Demuxer context update while decoder is open, closing and trying to re-open\n"); + ret = codec_close(sti); + sti->info->found_decoder = 0; + if (ret < 0) + return ret; + } + /* close parser, because it depends on the codec */ if (sti->parser && sti->avctx->codec_id != st->codecpar->codec_id) { av_parser_close(sti->parser); @@ -797,9 +807,14 @@ static int64_t select_from_pts_buffer(AVStream *st, int64_t *pts_buffer, int64_t } else { for (int i = 0; i < delay; i++) { if (pts_buffer[i] != AV_NOPTS_VALUE) { - int64_t diff = FFABS(pts_buffer[i] - dts) - + (uint64_t)sti->pts_reorder_error[i]; - diff = FFMAX(diff, sti->pts_reorder_error[i]); +#define ABSDIFF(a,b) (((a) < (b)) ? (b) - (uint64_t)(a) : ((a) - (uint64_t)(b))) + uint64_t diff = ABSDIFF(pts_buffer[i], dts); + + if (diff > INT64_MAX - sti->pts_reorder_error[i]) { + diff = INT64_MAX; + } else + diff += sti->pts_reorder_error[i]; + sti->pts_reorder_error[i] = diff; sti->pts_reorder_error_count[i]++; if (sti->pts_reorder_error_count[i] > 250) { @@ -2646,6 +2661,13 @@ int avformat_find_stream_info(AVFormatContext *ic, AVDictionary **options) break; } + /* read_frame_internal() in a previous iteration of this loop may + * have made changes to streams without returning a packet for them. + * Handle that here. */ + ret = update_stream_avctx(ic); + if (ret < 0) + goto unref_then_goto_end; + /* check if one codec still needs to be handled */ for (i = 0; i < ic->nb_streams; i++) { AVStream *const st = ic->streams[i]; diff --git a/libavformat/dhav.c b/libavformat/dhav.c index b2ead9960..17ae1e30f 100644 --- a/libavformat/dhav.c +++ b/libavformat/dhav.c @@ -297,7 +297,9 @@ static int dhav_read_header(AVFormatContext *s) if (seek_back < 9) break; dhav->last_good_pos = avio_tell(s->pb); - avio_seek(s->pb, -seek_back, SEEK_CUR); + int64_t ret64 = avio_seek(s->pb, -seek_back, SEEK_CUR); + if (ret64 < 0) + return ret64; } avio_seek(s->pb, dhav->last_good_pos, SEEK_SET); } diff --git a/libavformat/dss.c b/libavformat/dss.c index 47c8f49d6..13164631b 100644 --- a/libavformat/dss.c +++ b/libavformat/dss.c @@ -26,6 +26,7 @@ #include "avformat.h" #include "demux.h" #include "internal.h" +#include "avio_internal.h" #define DSS_HEAD_OFFSET_AUTHOR 0xc #define DSS_AUTHOR_SIZE 16 @@ -338,7 +339,9 @@ static int dss_read_seek(AVFormatContext *s, int stream_index, if (ret < 0) return ret; - avio_read(s->pb, header, DSS_AUDIO_BLOCK_HEADER_SIZE); + ret = ffio_read_size(s->pb, header, DSS_AUDIO_BLOCK_HEADER_SIZE); + if (ret < 0) + return ret; ctx->swap = !!(header[0] & 0x80); offset = 2*header[1] + 2*ctx->swap; if (offset < DSS_AUDIO_BLOCK_HEADER_SIZE) diff --git a/libavformat/dtshddec.c b/libavformat/dtshddec.c index 28d3aeb47..97bc83793 100644 --- a/libavformat/dtshddec.c +++ b/libavformat/dtshddec.c @@ -26,6 +26,7 @@ #include "avformat.h" #include "demux.h" #include "internal.h" +#include "avio_internal.h" #define AUPR_HDR 0x415550522D484452 #define AUPRINFO 0x41555052494E464F @@ -119,7 +120,11 @@ static int dtshd_read_header(AVFormatContext *s) value = av_malloc(chunk_size); if (!value) goto skip; - avio_read(pb, value, chunk_size); + ret = ffio_read_size(pb, value, chunk_size); + if (ret < 0) { + av_free(value); + goto skip; + } value[chunk_size - 1] = 0; av_dict_set(&s->metadata, "fileinfo", value, AV_DICT_DONT_STRDUP_VAL); diff --git a/libavformat/flac_picture.c b/libavformat/flac_picture.c index c9f3f11ed..46f051321 100644 --- a/libavformat/flac_picture.c +++ b/libavformat/flac_picture.c @@ -23,6 +23,7 @@ #include "libavcodec/bytestream.h" #include "libavcodec/png.h" #include "avformat.h" +#include "avio_internal.h" #include "demux.h" #include "flac_picture.h" #include "id3v2.h" @@ -158,8 +159,9 @@ int ff_flac_parse_picture(AVFormatContext *s, uint8_t **bufp, int buf_size, // If truncation was detected copy all data from block and // read missing bytes not included in the block size. bytestream2_get_bufferu(&g, data->data, left); - if (avio_read(s->pb, data->data + len - trunclen, trunclen) < trunclen) - RETURN_ERROR(AVERROR_INVALIDDATA); + ret = ffio_read_size(s->pb, data->data + len - trunclen, trunclen); + if (ret < 0) + goto fail; } } memset(data->data + len, 0, AV_INPUT_BUFFER_PADDING_SIZE); diff --git a/libavformat/flvdec.c b/libavformat/flvdec.c index 1fb3e0cd3..7e332e9a3 100644 --- a/libavformat/flvdec.c +++ b/libavformat/flvdec.c @@ -1465,6 +1465,10 @@ retry_duration: if (st->codecpar->codec_id == AV_CODEC_ID_H264 || st->codecpar->codec_id == AV_CODEC_ID_MPEG4 || (st->codecpar->codec_id == AV_CODEC_ID_HEVC && type == PacketTypeCodedFrames)) { + if (size < 3) { + ret = AVERROR_INVALIDDATA; + goto leave; + } // sign extension int32_t cts = (avio_rb24(s->pb) + 0xff800000) ^ 0xff800000; pts = av_sat_add64(dts, cts); diff --git a/libavformat/g726.c b/libavformat/g726.c index e783fa412..05b7ba3d3 100644 --- a/libavformat/g726.c +++ b/libavformat/g726.c @@ -98,4 +98,3 @@ const FFInputFormat ff_g726le_demuxer = { .raw_codec_id = AV_CODEC_ID_ADPCM_G726LE, }; #endif - diff --git a/libavformat/hls.c b/libavformat/hls.c index fe008eee9..4d52b50a5 100644 --- a/libavformat/hls.c +++ b/libavformat/hls.c @@ -966,13 +966,22 @@ static int parse_playlist(HLSContext *c, const char *url, if (pls) pls->finished = 1; } else if (av_strstart(line, "#EXTINF:", &ptr)) { + double d = atof(ptr) * AV_TIME_BASE; + if (d < 0 || d > INT64_MAX || isnan(d)) { + av_log(c->ctx, AV_LOG_WARNING, "EXTINF %f unsupported\n", d / AV_TIME_BASE); + d = 0; + } + duration = d; is_segment = 1; - duration = atof(ptr) * AV_TIME_BASE; } else if (av_strstart(line, "#EXT-X-BYTERANGE:", &ptr)) { seg_size = strtoll(ptr, NULL, 10); ptr = strchr(ptr, '@'); if (ptr) seg_offset = strtoll(ptr+1, NULL, 10); + if (seg_size < 0 || seg_offset > INT64_MAX - seg_size) { + ret = AVERROR_INVALIDDATA; + goto fail; + } } else if (av_strstart(line, "#", NULL)) { av_log(c->ctx, AV_LOG_INFO, "Skip ('%s')\n", line); continue; diff --git a/libavformat/hls_sample_encryption.c b/libavformat/hls_sample_encryption.c index f9f410f3d..26de098dd 100644 --- a/libavformat/hls_sample_encryption.c +++ b/libavformat/hls_sample_encryption.c @@ -88,6 +88,7 @@ void ff_hls_senc_read_audio_setup_info(HLSAudioSetupInfo *info, const uint8_t *b return; memcpy(info->setup_data, buf, info->setup_data_length); + memset(info->setup_data + info->setup_data_length, 0, AV_INPUT_BUFFER_PADDING_SIZE); } int ff_hls_senc_parse_audio_setup_info(AVStream *st, HLSAudioSetupInfo *info) diff --git a/libavformat/hls_sample_encryption.h b/libavformat/hls_sample_encryption.h index d86eccb74..0f7e1c3ec 100644 --- a/libavformat/hls_sample_encryption.h +++ b/libavformat/hls_sample_encryption.h @@ -52,7 +52,7 @@ typedef struct HLSAudioSetupInfo { uint16_t priming; uint8_t version; uint8_t setup_data_length; - uint8_t setup_data[HLS_MAX_AUDIO_SETUP_DATA_LEN]; + uint8_t setup_data[HLS_MAX_AUDIO_SETUP_DATA_LEN + AV_INPUT_BUFFER_PADDING_SIZE]; } HLSAudioSetupInfo; @@ -63,4 +63,3 @@ int ff_hls_senc_parse_audio_setup_info(AVStream *st, HLSAudioSetupInfo *info); int ff_hls_senc_decrypt_frame(enum AVCodecID codec_id, HLSCryptoContext *crypto_ctx, AVPacket *pkt); #endif /* AVFORMAT_HLS_SAMPLE_ENCRYPTION_H */ - diff --git a/libavformat/hlsplaylist.c b/libavformat/hlsplaylist.c index f8a697770..bcd257aea 100644 --- a/libavformat/hlsplaylist.c +++ b/libavformat/hlsplaylist.c @@ -199,4 +199,3 @@ void ff_hls_write_end_list(AVIOContext *out) return; avio_printf(out, "#EXT-X-ENDLIST\n"); } - diff --git a/libavformat/http.c b/libavformat/http.c index b674171d3..2ee4d71fb 100644 --- a/libavformat/http.c +++ b/libavformat/http.c @@ -22,6 +22,7 @@ #include "config.h" #include "config_components.h" +#include #include #if CONFIG_ZLIB #include @@ -143,6 +144,7 @@ typedef struct HTTPContext { unsigned int retry_after; int reconnect_max_retries; int reconnect_delay_total_max; + int max_redirects; } HTTPContext; #define OFFSET(x) offsetof(HTTPContext, x) @@ -188,6 +190,7 @@ static const AVOption options[] = { { "resource", "The resource requested by a client", OFFSET(resource), AV_OPT_TYPE_STRING, { .str = NULL }, 0, 0, E }, { "reply_code", "The http status code to return to a client", OFFSET(reply_code), AV_OPT_TYPE_INT, { .i64 = 200}, INT_MIN, 599, E}, { "short_seek_size", "Threshold to favor readahead over seek.", OFFSET(short_seek_size), AV_OPT_TYPE_INT, { .i64 = 0 }, 0, INT_MAX, D }, + { "max_redirects", "Maximum number of redirects", OFFSET(max_redirects), AV_OPT_TYPE_INT, { .i64 = MAX_REDIRECTS }, 0, INT_MAX, D }, { NULL } }; @@ -212,7 +215,7 @@ static int http_open_cnx_internal(URLContext *h, AVDictionary **options) const char *path, *proxy_path, *lower_proto = "tcp", *local_path; char *env_http_proxy, *env_no_proxy; char *hashmark; - char hostname[1024], hoststr[1024], proto[10]; + char hostname[1024], hoststr[1024], proto[10], tmp_host[1024]; char auth[1024], proxyauth[1024] = ""; char path1[MAX_URL_SIZE], sanitized_path[MAX_URL_SIZE + 1]; char buf[1024], urlbuf[MAX_URL_SIZE]; @@ -222,7 +225,14 @@ static int http_open_cnx_internal(URLContext *h, AVDictionary **options) av_url_split(proto, sizeof(proto), auth, sizeof(auth), hostname, sizeof(hostname), &port, path1, sizeof(path1), s->location); - ff_url_join(hoststr, sizeof(hoststr), NULL, NULL, hostname, port, NULL); + + av_strlcpy(tmp_host, hostname, sizeof(tmp_host)); + // In case of an IPv6 address, we need to strip the Zone ID, + // if any. We do it at the first % sign, as percent encoding + // can be used in the Zone ID itself. + if (strchr(tmp_host, ':')) + tmp_host[strcspn(tmp_host, "%")] = '\0'; + ff_url_join(hoststr, sizeof(hoststr), NULL, NULL, tmp_host, port, NULL); env_http_proxy = getenv_utf8("http_proxy"); proxy_path = s->http_proxy ? s->http_proxy : env_http_proxy; @@ -243,7 +253,11 @@ static int http_open_cnx_internal(URLContext *h, AVDictionary **options) if (err < 0) goto end; } + } else if (strcmp(proto, "http")) { + err = AVERROR(EINVAL); + goto end; } + if (port < 0) port = 80; @@ -374,6 +388,9 @@ redo: cached = redirect_cache_get(s); if (cached) { + if (redirects++ >= s->max_redirects) + return AVERROR(EIO); + av_free(s->location); s->location = av_strdup(cached); if (!s->location) { @@ -442,7 +459,7 @@ redo: s->new_location) { /* url moved, get next */ ffurl_closep(&s->hd); - if (redirects++ >= MAX_REDIRECTS) + if (redirects++ >= s->max_redirects) return AVERROR(EIO); if (!s->expires) { diff --git a/libavformat/iamf_parse.c b/libavformat/iamf_parse.c index a7a2b7deb..80755a884 100644 --- a/libavformat/iamf_parse.c +++ b/libavformat/iamf_parse.c @@ -38,7 +38,7 @@ static int opus_decoder_config(IAMFCodecConfig *codec_config, { int ret, left = len - avio_tell(pb); - if (left < 11 || codec_config->audio_roll_distance >= 0) + if (left < 11 || codec_config->audio_roll_distance >= 0 || left > INT_MAX - 8) return AVERROR_INVALIDDATA; codec_config->extradata = av_malloc(left + 8); @@ -398,6 +398,9 @@ static int scalable_channel_layout_config(void *s, AVIOContext *pb, .nb_channels = substream_count + coupled_substream_count }; + if (i && layer->ch_layout.nb_channels <= audio_element->element->layers[i-1]->ch_layout.nb_channels) + return AVERROR_INVALIDDATA; + for (int j = 0; j < substream_count; j++) { IAMFSubStream *substream = &audio_element->substreams[k++]; @@ -411,6 +414,9 @@ static int scalable_channel_layout_config(void *s, AVIOContext *pb, } + if (k != audio_element->nb_substreams) + return AVERROR_INVALIDDATA; + return 0; } @@ -481,7 +487,7 @@ static int ambisonics_config(void *s, AVIOContext *pb, return AVERROR(ENOMEM); for (int i = 0; i < demixing_matrix_size; i++) - layer->demixing_matrix[i] = av_make_q(sign_extend(avio_rb16(pb), 16), 1 << 8); + layer->demixing_matrix[i] = av_make_q(sign_extend(avio_rb16(pb), 16), 1 << 15); for (int i = 0; i < substream_count; i++) { IAMFSubStream *substream = &audio_element->substreams[i]; diff --git a/libavformat/iamf_reader.c b/libavformat/iamf_reader.c index d331e1315..9a8371d9e 100644 --- a/libavformat/iamf_reader.c +++ b/libavformat/iamf_reader.c @@ -31,10 +31,10 @@ #include "iamf_parse.h" #include "iamf_reader.h" -static AVStream *find_stream_by_id(AVFormatContext *s, int id) +static AVStream *find_stream_by_id(AVFormatContext *s, int id, int stream_id_offset) { for (int i = 0; i < s->nb_streams; i++) - if (s->streams[i]->id == id) + if (s->streams[i]->id == id + stream_id_offset) return s->streams[i]; av_log(s, AV_LOG_ERROR, "Invalid stream id %d\n", id); @@ -45,7 +45,7 @@ static int audio_frame_obu(AVFormatContext *s, const IAMFDemuxContext *c, AVIOContext *pb, AVPacket *pkt, int len, enum IAMF_OBU_Type type, unsigned skip_samples, unsigned discard_padding, - int id_in_bitstream) + int stream_id_offset, int id_in_bitstream) { AVStream *st; int ret, audio_substream_id; @@ -59,7 +59,7 @@ static int audio_frame_obu(AVFormatContext *s, const IAMFDemuxContext *c, } else audio_substream_id = type - IAMF_OBU_IA_AUDIO_FRAME_ID0; - st = find_stream_by_id(s, audio_substream_id); + st = find_stream_by_id(s, audio_substream_id, stream_id_offset); if (!st) return AVERROR_INVALIDDATA; @@ -95,6 +95,9 @@ static int audio_frame_obu(AVFormatContext *s, const IAMFDemuxContext *c, memcpy(side_data, c->recon, c->recon_size); } + if (st->discard == AVDISCARD_ALL) + pkt->flags |= AV_PKT_FLAG_DISCARD; + pkt->stream_index = st->index; return 0; } @@ -277,7 +280,7 @@ fail: } int ff_iamf_read_packet(AVFormatContext *s, IAMFDemuxContext *c, - AVIOContext *pb, int max_size, AVPacket *pkt) + AVIOContext *pb, int max_size, int stream_id_offset, AVPacket *pkt) { int read = 0; @@ -308,7 +311,7 @@ int ff_iamf_read_packet(AVFormatContext *s, IAMFDemuxContext *c, read += len; if (type >= IAMF_OBU_IA_AUDIO_FRAME && type <= IAMF_OBU_IA_AUDIO_FRAME_ID17) { ret = audio_frame_obu(s, c, pb, pkt, obu_size, type, - skip_samples, discard_padding, + skip_samples, discard_padding, stream_id_offset, type == IAMF_OBU_IA_AUDIO_FRAME); if (ret < 0) return ret; diff --git a/libavformat/iamf_reader.h b/libavformat/iamf_reader.h index ecb92d485..279739cde 100644 --- a/libavformat/iamf_reader.h +++ b/libavformat/iamf_reader.h @@ -42,7 +42,7 @@ typedef struct IAMFDemuxContext { } IAMFDemuxContext; int ff_iamf_read_packet(AVFormatContext *s, IAMFDemuxContext *c, - AVIOContext *pb, int max_size, AVPacket *pkt); + AVIOContext *pb, int max_size, int stream_id_offset, AVPacket *pkt); void ff_iamf_read_deinit(IAMFDemuxContext *c); diff --git a/libavformat/iamf_writer.c b/libavformat/iamf_writer.c index 27926f859..163d7e120 100644 --- a/libavformat/iamf_writer.c +++ b/libavformat/iamf_writer.c @@ -125,9 +125,14 @@ static int fill_codec_config(IAMFContext *iamf, const AVStreamGroup *stg, } populate_audio_roll_distance(codec_config); if (st->codecpar->extradata_size) { - codec_config->extradata = av_memdup(st->codecpar->extradata, st->codecpar->extradata_size); + if (st->codecpar->extradata_size > INT_MAX - AV_INPUT_BUFFER_PADDING_SIZE) + return AVERROR_INVALIDDATA; + + codec_config->extradata = av_malloc(st->codecpar->extradata_size + AV_INPUT_BUFFER_PADDING_SIZE); if (!codec_config->extradata) return AVERROR(ENOMEM); + memcpy(codec_config->extradata, st->codecpar->extradata, st->codecpar->extradata_size); + memset(codec_config->extradata + st->codecpar->extradata_size, 0, AV_INPUT_BUFFER_PADDING_SIZE); codec_config->extradata_size = st->codecpar->extradata_size; ret = update_extradata(codec_config); if (ret < 0) @@ -583,11 +588,15 @@ static int ambisonics_config(const IAMFAudioElement *audio_element, AVIOContext *dyn_bc) { const AVIAMFAudioElement *element = audio_element->celement; + const IAMFLayer *ilayer = &audio_element->layers[0]; const AVIAMFLayer *layer = element->layers[0]; + if (audio_element->nb_substreams != ilayer->substream_count) + return AVERROR(EINVAL); + ffio_write_leb(dyn_bc, 0); // ambisonics_mode - ffio_write_leb(dyn_bc, layer->ch_layout.nb_channels); // output_channel_count - ffio_write_leb(dyn_bc, audio_element->nb_substreams); // substream_count + avio_w8(dyn_bc, layer->ch_layout.nb_channels); // output_channel_count + avio_w8(dyn_bc, audio_element->nb_substreams); // substream_count if (layer->ch_layout.order == AV_CHANNEL_ORDER_AMBISONIC) for (int i = 0; i < layer->ch_layout.nb_channels; i++) @@ -1109,7 +1118,7 @@ int ff_iamf_write_audio_frame(const IAMFContext *iamf, AVIOContext *pb, AV_PKT_DATA_NEW_EXTRADATA, &new_extradata_size); - if (!new_extradata) + if (!new_extradata || new_extradata_size > INT_MAX - AV_INPUT_BUFFER_PADDING_SIZE) return AVERROR_INVALIDDATA; audio_element = get_audio_element(iamf, audio_substream_id); if (!audio_element) @@ -1119,11 +1128,13 @@ int ff_iamf_write_audio_frame(const IAMFContext *iamf, AVIOContext *pb, return AVERROR(EINVAL); av_free(codec_config->extradata); - codec_config->extradata = av_memdup(new_extradata, new_extradata_size); + codec_config->extradata = av_malloc(new_extradata_size + AV_INPUT_BUFFER_PADDING_SIZE); if (!codec_config->extradata) { codec_config->extradata_size = 0; return AVERROR(ENOMEM); } + memcpy(codec_config->extradata, new_extradata, new_extradata_size); + memset(codec_config->extradata + new_extradata_size, 0, AV_INPUT_BUFFER_PADDING_SIZE); codec_config->extradata_size = new_extradata_size; return update_extradata(codec_config); diff --git a/libavformat/iamfdec.c b/libavformat/iamfdec.c index ce6d4aa06..8feb06d9e 100644 --- a/libavformat/iamfdec.c +++ b/libavformat/iamfdec.c @@ -165,7 +165,7 @@ static int iamf_read_packet(AVFormatContext *s, AVPacket *pkt) IAMFDemuxContext *const c = s->priv_data; int ret; - ret = ff_iamf_read_packet(s, c, s->pb, INT_MAX, pkt); + ret = ff_iamf_read_packet(s, c, s->pb, INT_MAX, 0, pkt); if (ret < 0) return ret; diff --git a/libavformat/icodec.c b/libavformat/icodec.c index b09d0060a..4eddc8fa3 100644 --- a/libavformat/icodec.c +++ b/libavformat/icodec.c @@ -113,7 +113,7 @@ static int read_header(AVFormatContext *s) avio_skip(pb, 5); ico->images[i].size = avio_rl32(pb); - if (ico->images[i].size <= 0) { + if (ico->images[i].size <= 0 || ico->images[i].size > INT_MAX - 14) { av_log(s, AV_LOG_ERROR, "Invalid image size %d\n", ico->images[i].size); return AVERROR_INVALIDDATA; } diff --git a/libavformat/iff.c b/libavformat/iff.c index 82d31811a..83549f1a0 100644 --- a/libavformat/iff.c +++ b/libavformat/iff.c @@ -340,8 +340,10 @@ static int parse_dsd_prop(AVFormatContext *s, AVStream *st, uint64_t eof) if (config != 0xFFFF) { if (config < FF_ARRAY_ELEMS(dsd_loudspeaker_config)) st->codecpar->ch_layout = dsd_loudspeaker_config[config]; - if (!st->codecpar->ch_layout.nb_channels) + if (!st->codecpar->ch_layout.nb_channels) { avpriv_request_sample(s, "loudspeaker configuration %d", config); + return AVERROR_PATCHWELCOME; + } } break; } diff --git a/libavformat/img2dec.c b/libavformat/img2dec.c index 3389fa818..40dd95cbe 100644 --- a/libavformat/img2dec.c +++ b/libavformat/img2dec.c @@ -416,8 +416,9 @@ int ff_img_read_packet(AVFormatContext *s1, AVPacket *pkt) char filename_bytes[1024]; char *filename = filename_bytes; int i, res; - int size[3] = { 0 }, ret[3] = { 0 }; - AVIOContext *f[3] = { NULL }; + int ret[3] = { 0 }; + int64_t size[3] = { 0 }; + AVIOContext *f[3] = { NULL }; AVCodecParameters *par = s1->streams[0]->codecpar; if (!s->is_pipe) { @@ -497,7 +498,15 @@ int ff_img_read_packet(AVFormatContext *s1, AVPacket *pkt) } } - res = av_new_packet(pkt, size[0] + size[1] + size[2]); + int total_size = 0; + for (int i = 0; i < 3; i++) { + if ((uint64_t)size[i] > INT_MAX - total_size) + return AVERROR_INVALIDDATA; + + total_size += size[i]; + } + + res = av_new_packet(pkt, total_size); if (res < 0) { goto fail; } diff --git a/libavformat/img2enc.c b/libavformat/img2enc.c index 41638d92b..c4dbd2629 100644 --- a/libavformat/img2enc.c +++ b/libavformat/img2enc.c @@ -207,6 +207,11 @@ static int write_packet(AVFormatContext *s, AVPacket *pkt) ysize *= 2; usize *= 2; } + if (ysize + 2*usize + (desc->nb_components > 3) * ysize > pkt->size) { + ret = AVERROR(EINVAL); + goto fail; + } + if ((ret = write_and_close(s, &pb[0], pkt->data , ysize)) < 0 || (ret = write_and_close(s, &pb[1], pkt->data + ysize , usize)) < 0 || (ret = write_and_close(s, &pb[2], pkt->data + ysize + usize, usize)) < 0) diff --git a/libavformat/isom.h b/libavformat/isom.h index ffabc01a2..f18fe541c 100644 --- a/libavformat/isom.h +++ b/libavformat/isom.h @@ -273,6 +273,7 @@ typedef struct MOVStreamContext { } cenc; struct IAMFDemuxContext *iamf; + int iamf_stream_offset; } MOVStreamContext; typedef struct HEIFItem { diff --git a/libavformat/lrcdec.c b/libavformat/lrcdec.c index f4a879954..9ee7200ac 100644 --- a/libavformat/lrcdec.c +++ b/libavformat/lrcdec.c @@ -89,7 +89,7 @@ static int64_t read_ts(const char *p, int64_t *start) return 0; } int ret = sscanf(p, "%2[[-]%"SCNu32":%lf]", prefix, &mm, &ss); - if (ret != 3 || prefix[0] != '[' || ss < 0 || ss > 60) { + if (ret != 3 || prefix[0] != '[' || ss < 0 || ss > 60 || !isfinite(ss)) { return 0; } *start = llrint((mm * 60 + ss) * AV_TIME_BASE); diff --git a/libavformat/matroskadec.c b/libavformat/matroskadec.c index b6af422a4..3ada67ea7 100644 --- a/libavformat/matroskadec.c +++ b/libavformat/matroskadec.c @@ -2784,6 +2784,10 @@ static int mka_parse_audio_codec(MatroskaTrack *track, AVCodecParameters *par, par->block_align = track->audio.sub_packet_size; *extradata_offset = 78; } + if (par->block_align <= 0 || + track->audio.sub_packet_h * (unsigned)track->audio.frame_size > INT_MAX || + track->audio.frame_size * track->audio.sub_packet_h < par->block_align) + return AVERROR_INVALIDDATA; track->audio.buf = av_malloc_array(track->audio.sub_packet_h, track->audio.frame_size); if (!track->audio.buf) @@ -4448,6 +4452,10 @@ static CueDesc get_cue_desc(AVFormatContext *s, int64_t ts, int64_t cues_start) // Clusters. cue_desc.end_offset = cues_start - matroska->segment_start; } + + if (cue_desc.end_time_ns < cue_desc.start_time_ns) + return (CueDesc) {-1, -1, -1, -1}; + return cue_desc; } diff --git a/libavformat/mlvdec.c b/libavformat/mlvdec.c index 20a6f3629..6c4b161b3 100644 --- a/libavformat/mlvdec.c +++ b/libavformat/mlvdec.c @@ -33,6 +33,7 @@ #include "avformat.h" #include "demux.h" #include "internal.h" +#include "avio_internal.h" #include "riff.h" #define MLV_VERSION "v2.0" @@ -67,12 +68,15 @@ static int check_file_header(AVIOContext *pb, uint64_t guid) { unsigned int size; uint8_t version[8]; + int ret; avio_skip(pb, 4); size = avio_rl32(pb); if (size < 52) return AVERROR_INVALIDDATA; - avio_read(pb, version, 8); + ret = ffio_read_size(pb, version, 8); + if (ret < 0) + return ret; if (memcmp(version, MLV_VERSION, 5) || avio_rl64(pb) != guid) return AVERROR_INVALIDDATA; avio_skip(pb, size - 24); @@ -90,7 +94,7 @@ static void read_string(AVFormatContext *avctx, AVIOContext *pb, const char *tag } ret = avio_read(pb, value, size); - if (ret != size || !value[0]) { + if (ret != size || !size || !value[0]) { av_free(value); return; } diff --git a/libavformat/mov.c b/libavformat/mov.c index 15631f684..eb9b4ac6b 100644 --- a/libavformat/mov.c +++ b/libavformat/mov.c @@ -925,10 +925,9 @@ static int mov_read_iacb(MOVContext *c, AVIOContext *pb, MOVAtom atom) return AVERROR(ENOMEM); iamf = &sc->iamf->iamf; - st->codecpar->extradata = av_malloc(descriptors_size); - if (!st->codecpar->extradata) - return AVERROR(ENOMEM); - st->codecpar->extradata_size = descriptors_size; + ret = ff_alloc_extradata(st->codecpar, descriptors_size); + if (ret < 0) + return ret; ret = avio_read(pb, st->codecpar->extradata, descriptors_size); if (ret != descriptors_size) @@ -3178,6 +3177,7 @@ fail: av_freep(&sc->extradata[j]); } + sc->stsd_count = 0; av_freep(&sc->extradata); av_freep(&sc->extradata_size); return ret; @@ -3616,6 +3616,9 @@ static int mov_read_sdtp(MOVContext *c, AVIOContext *pb, MOVAtom atom) av_freep(&sc->sdtp_data); sc->sdtp_count = 0; + if (entries < 0 || entries > SIZE_MAX) + return AVERROR(ERANGE); + sc->sdtp_data = av_malloc(entries); if (!sc->sdtp_data) return AVERROR(ENOMEM); @@ -4240,7 +4243,12 @@ static void mov_fix_index(MOVContext *mov, AVStream *st) st->index, edit_list_index, edit_list_media_time, edit_list_duration); edit_list_index++; edit_list_dts_counter = edit_list_dts_entry_end; - edit_list_dts_entry_end += edit_list_duration; + edit_list_dts_entry_end = av_sat_add64(edit_list_dts_entry_end, edit_list_duration); + if (edit_list_dts_entry_end == INT64_MAX) { + av_log(mov->fc, AV_LOG_ERROR, "Cannot calculate dts entry length with duration %"PRId64"\n", + edit_list_duration); + break; + } num_discarded_begin = 0; if (!found_non_empty_edit && edit_list_media_time == -1) { empty_edits_sum_duration += edit_list_duration; @@ -7905,7 +7913,7 @@ static int cenc_scheme_decrypt(MOVContext *c, MOVStreamContext *sc, AVEncryption } for (i = 0; i < sample->subsample_count; i++) { - if (sample->subsamples[i].bytes_of_clear_data + sample->subsamples[i].bytes_of_protected_data > size) { + if (sample->subsamples[i].bytes_of_clear_data + (int64_t)sample->subsamples[i].bytes_of_protected_data > size) { av_log(c->fc, AV_LOG_ERROR, "subsample size exceeds the packet size left\n"); return AVERROR_INVALIDDATA; } @@ -7960,7 +7968,7 @@ static int cbc1_scheme_decrypt(MOVContext *c, MOVStreamContext *sc, AVEncryption } for (i = 0; i < sample->subsample_count; i++) { - if (sample->subsamples[i].bytes_of_clear_data + sample->subsamples[i].bytes_of_protected_data > size) { + if (sample->subsamples[i].bytes_of_clear_data + (int64_t)sample->subsamples[i].bytes_of_protected_data > size) { av_log(c->fc, AV_LOG_ERROR, "subsample size exceeds the packet size left\n"); return AVERROR_INVALIDDATA; } @@ -8022,7 +8030,7 @@ static int cens_scheme_decrypt(MOVContext *c, MOVStreamContext *sc, AVEncryption } for (i = 0; i < sample->subsample_count; i++) { - if (sample->subsamples[i].bytes_of_clear_data + sample->subsamples[i].bytes_of_protected_data > size) { + if (sample->subsamples[i].bytes_of_clear_data + (int64_t)sample->subsamples[i].bytes_of_protected_data > size) { av_log(c->fc, AV_LOG_ERROR, "subsample size exceeds the packet size left\n"); return AVERROR_INVALIDDATA; } @@ -8087,7 +8095,7 @@ static int cbcs_scheme_decrypt(MOVContext *c, MOVStreamContext *sc, AVEncryption } for (i = 0; i < sample->subsample_count; i++) { - if (sample->subsamples[i].bytes_of_clear_data + sample->subsamples[i].bytes_of_protected_data > size) { + if (sample->subsamples[i].bytes_of_clear_data + (int64_t)sample->subsamples[i].bytes_of_protected_data > size) { av_log(c->fc, AV_LOG_ERROR, "subsample size exceeds the packet size left\n"); return AVERROR_INVALIDDATA; } @@ -8245,7 +8253,7 @@ static int mov_read_dops(MOVContext *c, AVIOContext *pb, MOVAtom atom) return 0; st = c->fc->streams[c->fc->nb_streams-1]; - if ((uint64_t)atom.size > (1<<30) || atom.size < 11) + if ((uint64_t)atom.size > (1<<30) || atom.size < 11 || st->codecpar->extradata) return AVERROR_INVALIDDATA; /* Check OpusSpecificBox version. */ @@ -8263,7 +8271,11 @@ static int mov_read_dops(MOVContext *c, AVIOContext *pb, MOVAtom atom) AV_WL32A(st->codecpar->extradata, MKTAG('O','p','u','s')); AV_WL32A(st->codecpar->extradata + 4, MKTAG('H','e','a','d')); AV_WB8(st->codecpar->extradata + 8, 1); /* OpusHead version */ - avio_read(pb, st->codecpar->extradata + 9, size - 9); + if ((ret = ffio_read_size(pb, st->codecpar->extradata + 9, size - 9)) < 0) { + av_freep(&st->codecpar->extradata); + st->codecpar->extradata_size = 0; + return ret; + } /* OpusSpecificBox is stored in big-endian, but OpusHead is little-endian; aside from the preceeding magic and version they're @@ -8351,8 +8363,10 @@ static int mov_read_lhvc(MOVContext *c, AVIOContext *pb, MOVAtom atom) // TODO: handle lhvC when present before hvcC return 0; - if (atom.size < 6 || st->codecpar->extradata_size < 23) + if (atom.size < 6 || st->codecpar->extradata_size < 23 || + atom.size > INT_MAX - AV_INPUT_BUFFER_PADDING_SIZE) { return AVERROR_INVALIDDATA; + } buf = av_malloc(atom.size + AV_INPUT_BUFFER_PADDING_SIZE); if (!buf) @@ -8840,6 +8854,7 @@ static int mov_read_iref_dimg(MOVContext *c, AVIOContext *pb, int version) HEIFGrid *grid; int entries, i; int from_item_id = version ? avio_rb32(pb) : avio_rb16(pb); + int ret = 0; for (int i = 0; i < c->nb_heif_grid; i++) { if (c->heif_grid[i].item->item_id == from_item_id) { @@ -8869,28 +8884,43 @@ static int mov_read_iref_dimg(MOVContext *c, AVIOContext *pb, int version) return AVERROR_INVALIDDATA; } + entries = avio_rb16(pb); + if (!entries) { + av_log(c->fc, AV_LOG_ERROR, + "Derived image item references no input images\n"); + return AVERROR_INVALIDDATA; + } + grid = av_realloc_array(c->heif_grid, c->nb_heif_grid + 1U, sizeof(*c->heif_grid)); if (!grid) return AVERROR(ENOMEM); c->heif_grid = grid; - grid = &grid[c->nb_heif_grid++]; + grid = &grid[c->nb_heif_grid]; - entries = avio_rb16(pb); grid->tile_id_list = av_malloc_array(entries, sizeof(*grid->tile_id_list)); grid->tile_item_list = av_calloc(entries, sizeof(*grid->tile_item_list)); - if (!grid->tile_id_list || !grid->tile_item_list) - return AVERROR(ENOMEM); + if (!grid->tile_id_list || !grid->tile_item_list) { + ret = AVERROR(ENOMEM); + goto fail; + } /* 'to' item ids */ for (i = 0; i < entries; i++) grid->tile_id_list[i] = version ? avio_rb32(pb) : avio_rb16(pb); + grid->nb_tiles = entries; grid->item = item; + ++c->nb_heif_grid; av_log(c->fc, AV_LOG_TRACE, "dimg: from_item_id %d, entries %d\n", from_item_id, entries); return 0; +fail: + av_freep(&grid->tile_id_list); + av_freep(&grid->tile_item_list); + + return ret; } static int mov_read_iref_thmb(MOVContext *c, AVIOContext *pb, int version) @@ -8939,8 +8969,12 @@ static int mov_read_iref(MOVContext *c, AVIOContext *pb, MOVAtom atom) type = avio_rl32(pb); switch (type) { case MKTAG('d','i','m','g'): - mov_read_iref_dimg(c, pb, version); + { + int ret = mov_read_iref_dimg(c, pb, version); + if (ret < 0) + return ret; break; + } case MKTAG('t','h','m','b'): mov_read_iref_thmb(c, pb, version); break; @@ -10180,6 +10214,44 @@ static AVStream *mov_find_reference_track(AVFormatContext *s, AVStream *st, return NULL; } +static void fix_stream_ids(AVFormatContext *s) +{ + int highest_id = 0, lowest_iamf_id = INT_MAX; + + for (int i = 0; i < s->nb_streams; i++) { + const AVStream *st = s->streams[i]; + const MOVStreamContext *sc = st->priv_data; + if (!sc->iamf) + highest_id = FFMAX(highest_id, st->id); + } + + for (int i = 0; i < s->nb_stream_groups; i++) { + AVStreamGroup *stg = s->stream_groups[i]; + if (stg->type != AV_STREAM_GROUP_PARAMS_IAMF_AUDIO_ELEMENT) + continue; + for (int j = 0; j < stg->nb_streams; j++) { + AVStream *st = stg->streams[j]; + lowest_iamf_id = FFMIN(lowest_iamf_id, st->id); + } + } + + if (highest_id < lowest_iamf_id) + return; + + highest_id += !lowest_iamf_id; + for (int i = 0; highest_id > 1 && i < s->nb_stream_groups; i++) { + AVStreamGroup *stg = s->stream_groups[i]; + if (stg->type != AV_STREAM_GROUP_PARAMS_IAMF_AUDIO_ELEMENT) + continue; + for (int j = 0; j < stg->nb_streams; j++) { + AVStream *st = stg->streams[j]; + MOVStreamContext *sc = st->priv_data; + st->id += highest_id; + sc->iamf_stream_offset = highest_id; + } + } +} + static int mov_read_header(AVFormatContext *s) { MOVContext *mov = s->priv_data; @@ -10427,6 +10499,9 @@ static int mov_read_header(AVFormatContext *s) break; } } + + fix_stream_ids(s); + ff_configure_buffers_for_index(s, AV_TIME_BASE); for (i = 0; i < mov->frag_index.nb_items; i++) @@ -10688,7 +10763,7 @@ static int mov_read_packet(AVFormatContext *s, AVPacket *pkt) sample->size = FFMIN(sample->size, (mov->next_root_atom - sample->pos)); } - if (st->discard != AVDISCARD_ALL) { + if (st->discard != AVDISCARD_ALL || sc->iamf) { int64_t ret64 = avio_seek(sc->pb, sample->pos, SEEK_SET); if (ret64 != sample->pos) { av_log(mov->fc, AV_LOG_ERROR, "stream %d, offset 0x%"PRIx64": partial file\n", @@ -10717,13 +10792,19 @@ static int mov_read_packet(AVFormatContext *s, AVPacket *pkt) pos = pkt->pos; flags = pkt->flags; duration = pkt->duration; while (!ret && size > 0) { - ret = ff_iamf_read_packet(s, sc->iamf, sc->pb, size, pkt); + ret = ff_iamf_read_packet(s, sc->iamf, sc->pb, size, sc->iamf_stream_offset, pkt); if (ret < 0) { if (should_retry(sc->pb, ret)) mov_current_sample_dec(sc); return ret; } size -= ret; + + if (pkt->flags & AV_PKT_FLAG_DISCARD) { + av_packet_unref(pkt); + ret = 0; + continue; + } pkt->pts = pts; pkt->dts = dts; pkt->pos = pos; pkt->flags |= flags; pkt->duration = duration; diff --git a/libavformat/mpegts.c b/libavformat/mpegts.c index 86b7c8e04..c6af801f5 100644 --- a/libavformat/mpegts.c +++ b/libavformat/mpegts.c @@ -1680,7 +1680,7 @@ static int mp4_read_iods(AVFormatContext *s, const uint8_t *buf, unsigned size, ret = parse_mp4_descr(&d, avio_tell(&d.pb.pub), size, MP4IODescrTag); - *descr_count = d.descr_count; + *descr_count += d.descr_count; return ret; } @@ -2383,7 +2383,8 @@ static void pmt_cb(MpegTSFilter *filter, const uint8_t *section, int section_len av_log(ts->stream, AV_LOG_TRACE, "pcr_pid=0x%x\n", pcr_pid); program_info_length = get16(&p, p_end); - if (program_info_length < 0) + + if (program_info_length < 0 || (program_info_length & 0xFFF) > p_end - p) return; program_info_length &= 0xfff; while (program_info_length >= 2) { @@ -2398,12 +2399,12 @@ static void pmt_cb(MpegTSFilter *filter, const uint8_t *section, int section_len // something else is broken, exit the program_descriptors_loop break; program_info_length -= len; - if (tag == IOD_DESCRIPTOR) { + if (tag == IOD_DESCRIPTOR && len >= 2) { get8(&p, p_end); // scope get8(&p, p_end); // label len -= 2; mp4_read_iods(ts->stream, p, len, mp4_descr + mp4_descr_count, - &mp4_descr_count, MAX_MP4_DESCR_COUNT); + &mp4_descr_count, MAX_MP4_DESCR_COUNT - mp4_descr_count); } else if (tag == REGISTRATION_DESCRIPTOR && len >= 4) { prog_reg_desc = bytestream_get_le32(&p); len -= 4; diff --git a/libavformat/mpegtsenc.c b/libavformat/mpegtsenc.c index 215783f32..42ecc3b28 100644 --- a/libavformat/mpegtsenc.c +++ b/libavformat/mpegtsenc.c @@ -57,6 +57,7 @@ typedef struct MpegTSSection { int discontinuity; void (*write_packet)(struct MpegTSSection *s, const uint8_t *packet); void *opaque; + int remaining; } MpegTSSection; typedef struct MpegTSService { @@ -1016,6 +1017,10 @@ static MpegTSService *mpegts_add_service(AVFormatContext *s, int sid, av_log(s, AV_LOG_ERROR, "Too long service or provider name\n"); goto fail; } + ts->sdt.remaining -= 10 + service->provider_name[0] + service->name[0]; + if (ts->sdt.remaining < 0) + goto fail; + if (av_dynarray_add_nofree(&ts->services, &ts->nb_services, service) < 0) goto fail; @@ -1126,6 +1131,8 @@ static int mpegts_init(AVFormatContext *s) // round up to a whole number of TS packets ts->pes_payload_size = (ts->pes_payload_size + 14 + 183) / 184 * 184 - 14; + ts->sdt.remaining = SECTION_LENGTH - 3; + if (!s->nb_programs) { /* allocate a single DVB service */ if (!mpegts_add_service(s, ts->service_id, s->metadata, NULL)) diff --git a/libavformat/pcm.c b/libavformat/pcm.c index a774dbc37..bea3a1443 100644 --- a/libavformat/pcm.c +++ b/libavformat/pcm.c @@ -74,7 +74,8 @@ int ff_pcm_read_seek(AVFormatContext *s, int stream_index, int64_t timestamp, int flags) { AVStream *st; - int block_align, byte_rate; + int block_align; + int64_t byte_rate; int64_t pos, ret; st = s->streams[0]; @@ -82,9 +83,9 @@ int ff_pcm_read_seek(AVFormatContext *s, block_align = st->codecpar->block_align ? st->codecpar->block_align : (av_get_bits_per_sample(st->codecpar->codec_id) * st->codecpar->ch_layout.nb_channels) >> 3; byte_rate = st->codecpar->bit_rate ? st->codecpar->bit_rate >> 3 : - block_align * st->codecpar->sample_rate; + block_align * (int64_t)st->codecpar->sample_rate; - if (block_align <= 0 || byte_rate <= 0) + if (block_align <= 0 || byte_rate <= 0 || FFMAX(timestamp, st->time_base.num) > INT64_MAX / byte_rate) return -1; if (timestamp < 0) timestamp = 0; @@ -93,6 +94,9 @@ int ff_pcm_read_seek(AVFormatContext *s, st->time_base.num, st->time_base.den * (int64_t)block_align, (flags & AVSEEK_FLAG_BACKWARD) ? AV_ROUND_DOWN : AV_ROUND_UP); + + if (pos > (INT64_MAX - FFMAX(ffformatcontext(s)->data_offset, 0)) / block_align) + return -1; pos *= block_align; /* recompute exact position */ diff --git a/libavformat/rdt.c b/libavformat/rdt.c index 2fa53d34a..bb2accfd2 100644 --- a/libavformat/rdt.c +++ b/libavformat/rdt.c @@ -573,4 +573,3 @@ RDT_HANDLER(live_video, "x-pn-multirate-realvideo-live", AVMEDIA_TYPE_VIDEO); RDT_HANDLER(live_audio, "x-pn-multirate-realaudio-live", AVMEDIA_TYPE_AUDIO); RDT_HANDLER(video, "x-pn-realvideo", AVMEDIA_TYPE_VIDEO); RDT_HANDLER(audio, "x-pn-realaudio", AVMEDIA_TYPE_AUDIO); - diff --git a/libavformat/rsd.c b/libavformat/rsd.c index b9098646f..8eb9f901e 100644 --- a/libavformat/rsd.c +++ b/libavformat/rsd.c @@ -22,6 +22,7 @@ #include "libavutil/intreadwrite.h" #include "avformat.h" #include "avio.h" +#include "avio_internal.h" #include "demux.h" #include "internal.h" @@ -131,9 +132,9 @@ static int rsd_read_header(AVFormatContext *s) return ret; for (i = 0; i < par->ch_layout.nb_channels; i++) { - if (avio_feof(pb)) - return AVERROR_EOF; - avio_read(s->pb, st->codecpar->extradata + 32 * i, 32); + ret = ffio_read_size(s->pb, st->codecpar->extradata + 32 * i, 32); + if (ret < 0) + return ret; avio_skip(s->pb, 8); } break; diff --git a/libavformat/rtmpproto.c b/libavformat/rtmpproto.c index 8a568271c..dfb9c4b3d 100644 --- a/libavformat/rtmpproto.c +++ b/libavformat/rtmpproto.c @@ -1199,6 +1199,10 @@ static int rtmp_calc_swfhash(URLContext *s) if (!memcmp(in_data, "CWS", 3)) { #if CONFIG_ZLIB int64_t out_size; + if (in_size < 8) { + ret = AVERROR_INVALIDDATA; + goto fail; + } /* Decompress the SWF player file using Zlib. */ if (!(out_data = av_malloc(8))) { ret = AVERROR(ENOMEM); @@ -2242,9 +2246,14 @@ static int update_offset(RTMPContext *rt, int size) { int old_flv_size; + if (size < 0) + return AVERROR(EINVAL); + // generate packet header and put data into buffer for FLV demuxer if (rt->flv_off < rt->flv_size) { // There is old unread data in the buffer, thus append at the end + if (rt->flv_size > INT_MAX - size) + return AVERROR(ERANGE); old_flv_size = rt->flv_size; rt->flv_size += size; } else { @@ -2271,7 +2280,11 @@ static int append_flv_data(RTMPContext *rt, RTMPPacket *pkt, int skip) rt->has_video = 1; } + if (size > INT_MAX - 15) + return AVERROR(ERANGE); old_flv_size = update_offset(rt, size + 15); + if (old_flv_size < 0) + return old_flv_size; if ((ret = av_reallocp(&rt->flv_data, rt->flv_size)) < 0) { rt->flv_size = rt->flv_off = 0; @@ -2401,48 +2414,50 @@ static int rtmp_parse_result(URLContext *s, RTMPContext *rt, RTMPPacket *pkt) static int handle_metadata(RTMPContext *rt, RTMPPacket *pkt) { int ret, old_flv_size, type; - const uint8_t *next; - uint8_t *p; + PutByteContext pbc; + GetByteContext gbc; uint32_t size; uint32_t ts, cts, pts = 0; old_flv_size = update_offset(rt, pkt->size); + if (old_flv_size < 0) + return old_flv_size; if ((ret = av_reallocp(&rt->flv_data, rt->flv_size)) < 0) { rt->flv_size = rt->flv_off = 0; return ret; } - next = pkt->data; - p = rt->flv_data + old_flv_size; + bytestream2_init(&gbc, pkt->data, pkt->size); + bytestream2_init_writer(&pbc, rt->flv_data, rt->flv_size); + bytestream2_skip_p(&pbc, old_flv_size); /* copy data while rewriting timestamps */ ts = pkt->timestamp; - while (next - pkt->data < pkt->size - RTMP_HEADER) { - type = bytestream_get_byte(&next); - size = bytestream_get_be24(&next); - cts = bytestream_get_be24(&next); - cts |= bytestream_get_byte(&next) << 24; + while (bytestream2_get_bytes_left(&gbc) > RTMP_HEADER) { + type = bytestream2_get_byte(&gbc); + size = bytestream2_get_be24(&gbc); + cts = bytestream2_get_be24(&gbc); + cts |= bytestream2_get_byte(&gbc) << 24; if (!pts) pts = cts; ts += cts - pts; pts = cts; - if (size + 3 + 4 > pkt->data + pkt->size - next) + if (size + 3 + 4 > bytestream2_get_bytes_left(&gbc)) break; - bytestream_put_byte(&p, type); - bytestream_put_be24(&p, size); - bytestream_put_be24(&p, ts); - bytestream_put_byte(&p, ts >> 24); - memcpy(p, next, size + 3 + 4); - p += size + 3; - bytestream_put_be32(&p, size + RTMP_HEADER); - next += size + 3 + 4; + bytestream2_put_byte(&pbc, type); + bytestream2_put_be24(&pbc, size); + bytestream2_put_be24(&pbc, ts); + bytestream2_put_byte(&pbc, ts >> 24); + bytestream2_copy_buffer(&pbc, &gbc, size + 3); + bytestream2_skip(&gbc, 4); + bytestream2_put_be32(&pbc, size + RTMP_HEADER); } - if (p != rt->flv_data + rt->flv_size) { + if (bytestream2_tell_p(&pbc) != rt->flv_size) { av_log(rt, AV_LOG_WARNING, "Incomplete flv packets in " "RTMP_PT_METADATA packet\n"); - rt->flv_size = p - rt->flv_data; + rt->flv_size = bytestream2_tell_p(&pbc); } return 0; @@ -2709,7 +2724,8 @@ static int rtmp_open(URLContext *s, const char *uri, int flags, AVDictionary **o if (rt->listen) ff_url_join(buf, sizeof(buf), "tcp", NULL, hostname, port, "?listen&listen_timeout=%d&tcp_nodelay=%d", - rt->listen_timeout * 1000, rt->tcp_nodelay); + rt->listen_timeout < 0 ? -1 : rt->listen_timeout * 1000, + rt->tcp_nodelay); else ff_url_join(buf, sizeof(buf), "tcp", NULL, hostname, port, "?tcp_nodelay=%d", rt->tcp_nodelay); } diff --git a/libavformat/rtpdec_jpeg.c b/libavformat/rtpdec_jpeg.c index 81036247c..3b0efc4e5 100644 --- a/libavformat/rtpdec_jpeg.c +++ b/libavformat/rtpdec_jpeg.c @@ -274,6 +274,12 @@ static int jpeg_parse_packet(AVFormatContext *ctx, PayloadContext *jpeg, av_log(ctx, AV_LOG_WARNING, "Only 8-bit precision is supported.\n"); if (qtable_len > 0) { + if (qtable_len != 128) { + av_log(ctx, AV_LOG_ERROR, "Invalid RTP/JPEG packet. Invalid qtable length %d.\n", qtable_len); + if (qtable_len%64 || qtable_len > 4*64) + return AVERROR_INVALIDDATA; + } + if (len < qtable_len) { av_log(ctx, AV_LOG_ERROR, "Too short RTP/JPEG packet.\n"); return AVERROR_INVALIDDATA; diff --git a/libavformat/rtpdec_latm.c b/libavformat/rtpdec_latm.c index 2b4478289..0754ff398 100644 --- a/libavformat/rtpdec_latm.c +++ b/libavformat/rtpdec_latm.c @@ -73,11 +73,15 @@ static int latm_parse_packet(AVFormatContext *ctx, PayloadContext *data, cur_len = 0; while (data->pos < data->len) { uint8_t val = data->buf[data->pos++]; + if (val > data->len - cur_len) { + av_log(ctx, AV_LOG_ERROR, "Malformed LATM packet\n"); + return AVERROR_INVALIDDATA; + } cur_len += val; if (val != 0xff) break; } - if (data->pos + cur_len > data->len) { + if (cur_len > data->len - data->pos) { av_log(ctx, AV_LOG_ERROR, "Malformed LATM packet\n"); return AVERROR(EIO); } diff --git a/libavformat/rtpdec_mpeg4.c b/libavformat/rtpdec_mpeg4.c index 6531632b2..3c4769794 100644 --- a/libavformat/rtpdec_mpeg4.c +++ b/libavformat/rtpdec_mpeg4.c @@ -134,7 +134,7 @@ static int rtp_parse_mp4_au(PayloadContext *data, const uint8_t *buf, int len) length in bits */ au_headers_length = AV_RB16(buf); - if (au_headers_length > RTP_MAX_PACKET_LENGTH) + if (au_headers_length == 0 || au_headers_length > RTP_MAX_PACKET_LENGTH) return -1; data->au_headers_length_bytes = (au_headers_length + 7) / 8; diff --git a/libavformat/rtpdec_qdm2.c b/libavformat/rtpdec_qdm2.c index dce3c48bc..9d71fe67d 100644 --- a/libavformat/rtpdec_qdm2.c +++ b/libavformat/rtpdec_qdm2.c @@ -186,8 +186,9 @@ static int qdm2_parse_subpacket(PayloadContext *qdm, AVStream *st, */ static int qdm2_restore_block(PayloadContext *qdm, AVStream *st, AVPacket *pkt) { - int to_copy, n, res, include_csum; + int to_copy, n, res; uint8_t *p, *csum_pos = NULL; + int include_csum = qdm->block_type == 2 || qdm->block_type == 4; /* create packet to hold subpkts into a superblock */ av_assert0(qdm->cache > 0); @@ -196,6 +197,11 @@ static int qdm2_restore_block(PayloadContext *qdm, AVStream *st, AVPacket *pkt) break; av_assert0(n < 0x80); + int min_size = 2 + (qdm->len[n] > 0xff) + 2*include_csum; + + if (qdm->block_size < min_size) + return AVERROR_INVALIDDATA; + if ((res = av_new_packet(pkt, qdm->block_size)) < 0) return res; memset(pkt->data, 0, pkt->size); @@ -211,7 +217,7 @@ static int qdm2_restore_block(PayloadContext *qdm, AVStream *st, AVPacket *pkt) *p++ = qdm->block_type; *p++ = qdm->len[n]; } - if ((include_csum = (qdm->block_type == 2 || qdm->block_type == 4))) { + if (include_csum) { csum_pos = p; p += 2; } diff --git a/libavformat/rtpenc.c b/libavformat/rtpenc.c index 7b4ae37d1..624293fee 100644 --- a/libavformat/rtpenc.c +++ b/libavformat/rtpenc.c @@ -33,7 +33,7 @@ static const AVOption options[] = { FF_RTP_FLAG_OPTS(RTPMuxContext, flags), { "payload_type", "Specify RTP payload type", offsetof(RTPMuxContext, payload_type), AV_OPT_TYPE_INT, {.i64 = -1 }, -1, 127, AV_OPT_FLAG_ENCODING_PARAM }, - { "ssrc", "Stream identifier", offsetof(RTPMuxContext, ssrc), AV_OPT_TYPE_INT, { .i64 = 0 }, INT_MIN, INT_MAX, AV_OPT_FLAG_ENCODING_PARAM }, + { "ssrc", "Stream identifier", offsetof(RTPMuxContext, ssrc), AV_OPT_TYPE_UINT, { .i64 = 0 }, 0, UINT32_MAX, AV_OPT_FLAG_ENCODING_PARAM }, { "cname", "CNAME to include in RTCP SR packets", offsetof(RTPMuxContext, cname), AV_OPT_TYPE_STRING, { .str = NULL }, 0, 0, AV_OPT_FLAG_ENCODING_PARAM }, { "seq", "Starting sequence number", offsetof(RTPMuxContext, seq), AV_OPT_TYPE_INT, { .i64 = -1 }, -1, 65535, AV_OPT_FLAG_ENCODING_PARAM }, { NULL }, diff --git a/libavformat/rtsp.c b/libavformat/rtsp.c index 5ea471b40..9f59f604d 100644 --- a/libavformat/rtsp.c +++ b/libavformat/rtsp.c @@ -585,9 +585,10 @@ static void sdp_parse_line(AVFormatContext *s, SDPParseState *s1, NULL, NULL, 0, p); if (proto[0] == '\0') { /* relative control URL */ - if (rtsp_st->control_url[strlen(rtsp_st->control_url)-1]!='/') - av_strlcat(rtsp_st->control_url, "/", - sizeof(rtsp_st->control_url)); + size_t len = strlen(rtsp_st->control_url); + if (len == 0 || rtsp_st->control_url[len - 1] != '/') + av_strlcat(rtsp_st->control_url, "/", + sizeof(rtsp_st->control_url)); av_strlcat(rtsp_st->control_url, p, sizeof(rtsp_st->control_url)); } else @@ -1205,9 +1206,12 @@ start: q = buf; for (;;) { ret = ffurl_read_complete(rt->rtsp_hd, &ch, 1); + if (ret != 1) { + ret = (ret < 0) ? ret : AVERROR(EIO); + av_log(s, AV_LOG_WARNING, "Failed reading RTSP data: %s\n", av_err2str(ret)); + return ret; + } av_log(s, AV_LOG_TRACE, "ret=%d c=%02x [%c]\n", ret, ch, ch); - if (ret != 1) - return ret < 0 ? ret : AVERROR(EIO); if (ch == '\n') break; if (ch == '$' && q == buf) { @@ -1237,6 +1241,7 @@ start: if (!strncmp(buf1, "RTSP/", 5)) { get_word(buf1, sizeof(buf1), &p); reply->status_code = atoi(buf1); + p += strspn(p, SPACE_CHARS); av_strlcpy(reply->reason, p, sizeof(reply->reason)); } else { av_strlcpy(reply->reason, buf1, sizeof(reply->reason)); // method @@ -1775,7 +1780,8 @@ redirect: } else if (!strcmp(proto, "satip")) { av_strlcpy(proto, "rtsp", sizeof(proto)); rt->server_type = RTSP_SERVER_SATIP; - } + } else if (strcmp(proto, "rtsp")) + return AVERROR_INVALIDDATA; if (*auth) { av_strlcpy(rt->auth, auth, sizeof(rt->auth)); @@ -1843,6 +1849,15 @@ redirect: } } + if (!rt->rtsp_hd->protocol_blacklist && s->protocol_blacklist) { + rt->rtsp_hd->protocol_blacklist = av_strdup(s->protocol_blacklist); + if (!rt->rtsp_hd->protocol_blacklist) { + av_dict_free(&options); + err = AVERROR(ENOMEM); + goto fail; + } + } + /* complete the connection */ if (ffurl_connect(rt->rtsp_hd, &options)) { av_dict_free(&options); diff --git a/libavformat/rtspdec.c b/libavformat/rtspdec.c index 10078ce2f..e85ade054 100644 --- a/libavformat/rtspdec.c +++ b/libavformat/rtspdec.c @@ -190,7 +190,7 @@ static int rtsp_read_announce(AVFormatContext *s) rtsp_send_reply(s, RTSP_STATUS_SERVICE, NULL, request.seq); return AVERROR_OPTION_NOT_FOUND; } - if (request.content_length) { + if (request.content_length > 0) { sdp = av_malloc(request.content_length + 1); if (!sdp) return AVERROR(ENOMEM); @@ -214,10 +214,10 @@ static int rtsp_read_announce(AVFormatContext *s) return 0; } av_log(s, AV_LOG_ERROR, - "Content-Length header value exceeds sdp allocated buffer (4KB)\n"); + "Invalid ANNOUNCE Content-Length %d\n", request.content_length); rtsp_send_reply(s, RTSP_STATUS_INTERNAL, - "Content-Length exceeds buffer size", request.seq); - return AVERROR(EIO); + "Invalid Content-Length", request.seq); + return AVERROR_INVALIDDATA; } static int rtsp_read_options(AVFormatContext *s) diff --git a/libavformat/scd.c b/libavformat/scd.c index ee118c166..75306bd4c 100644 --- a/libavformat/scd.c +++ b/libavformat/scd.c @@ -30,6 +30,7 @@ #include "libavutil/mem.h" #include "libavformat/internal.h" #include "avformat.h" +#include "avio_internal.h" #include "demux.h" #define SCD_MAGIC ((uint64_t)MKBETAG('S', 'E', 'D', 'B') << 32 | \ @@ -121,7 +122,7 @@ static int scd_read_offsets(AVFormatContext *s) SCDDemuxContext *ctx = s->priv_data; uint8_t buf[SCD_OFFSET_HEADER_SIZE]; - if ((ret = avio_read(s->pb, buf, SCD_OFFSET_HEADER_SIZE)) < 0) + if ((ret = ffio_read_size(s->pb, buf, SCD_OFFSET_HEADER_SIZE)) < 0) return ret; ctx->hdr.table0.count = AV_RB16(buf + 0); diff --git a/libavformat/segafilm.c b/libavformat/segafilm.c index e72d872f9..7118c9db1 100644 --- a/libavformat/segafilm.c +++ b/libavformat/segafilm.c @@ -161,7 +161,7 @@ static int film_read_header(AVFormatContext *s) st->codecpar->height = AV_RB32(&scratch[12]); if (film->video_type == AV_CODEC_ID_RAWVIDEO) { - if (scratch[20] == 24) { + if (film->version == 0 || scratch[20] == 24) { st->codecpar->format = AV_PIX_FMT_RGB24; } else { av_log(s, AV_LOG_ERROR, "raw video is using unhandled %dbpp\n", scratch[20]); diff --git a/libavformat/tests/movenc.c b/libavformat/tests/movenc.c index 23a827e97..32268a45e 100644 --- a/libavformat/tests/movenc.c +++ b/libavformat/tests/movenc.c @@ -46,38 +46,38 @@ static const uint8_t aac_extradata[] = { static const char *format = "mp4"; -AVFormatContext *ctx; -uint8_t iobuf[32768]; -AVDictionary *opts; +static AVFormatContext *ctx; +static uint8_t iobuf[32768]; +static AVDictionary *opts; -int write_file; -const char *cur_name; -FILE* out; -int out_size; -struct AVMD5* md5; -uint8_t hash[HASH_SIZE]; +static int write_file; +static const char *cur_name; +static FILE* out; +static int out_size; +static struct AVMD5* md5; +static uint8_t hash[HASH_SIZE]; -AVPacket *pkt; -AVStream *video_st, *audio_st, *id3_st; -int64_t audio_dts, video_dts; +static AVPacket *pkt; +static AVStream *video_st, *audio_st, *id3_st; +static int64_t audio_dts, video_dts; -int bframes; -int64_t duration; -int64_t audio_duration; -int frames; -int gop_size; -int64_t next_p_pts; -enum AVPictureType last_picture; -int skip_write; -int skip_write_audio; -int clear_duration; -int force_iobuf_size; -int do_interleave; -int fake_pkt_duration; +static int bframes; +static int64_t duration; +static int64_t audio_duration; +static int frames; +static int gop_size; +static int64_t next_p_pts; +static enum AVPictureType last_picture; +static int skip_write; +static int skip_write_audio; +static int clear_duration; +static int force_iobuf_size; +static int do_interleave; +static int fake_pkt_duration; -int num_warnings; +static int num_warnings; -int check_faults; +static int check_faults; static void count_warnings(void *avcl, int level, const char *fmt, va_list vl) diff --git a/libavformat/version.h b/libavformat/version.h index 70c554c19..66aa46542 100644 --- a/libavformat/version.h +++ b/libavformat/version.h @@ -32,7 +32,7 @@ #include "version_major.h" #define LIBAVFORMAT_VERSION_MINOR 7 -#define LIBAVFORMAT_VERSION_MICRO 100 +#define LIBAVFORMAT_VERSION_MICRO 102 #define LIBAVFORMAT_VERSION_INT AV_VERSION_INT(LIBAVFORMAT_VERSION_MAJOR, \ LIBAVFORMAT_VERSION_MINOR, \ diff --git a/libavformat/vividas.c b/libavformat/vividas.c index bec4ad7ce..7f940d75f 100644 --- a/libavformat/vividas.c +++ b/libavformat/vividas.c @@ -588,7 +588,9 @@ static int viv_read_header(AVFormatContext *s) block_type = avio_r8(pb); if (block_type == 22) { - avio_read(pb, keybuffer, 187); + ret = ffio_read_size(pb, keybuffer, 187); + if (ret < 0) + return ret; b22_key = decode_key(keybuffer); b22_size = avio_rl32(pb); } @@ -722,8 +724,10 @@ static int viv_read_packet(AVFormatContext *s, } last_start = viv->audio_subpackets[viv->n_audio_subpackets].start = (int)(off - avio_tell(pb)); - if (last_start < last) + if (last_start < last) { + viv->n_audio_subpackets = 0; return AVERROR_INVALIDDATA; + } viv->current_audio_subpacket = 0; } else { diff --git a/libavformat/wavdec.c b/libavformat/wavdec.c index 7748a2fbb..315c82c93 100644 --- a/libavformat/wavdec.c +++ b/libavformat/wavdec.c @@ -694,7 +694,8 @@ static int64_t find_guid(AVIOContext *pb, const uint8_t guid1[16]) int64_t size; while (!avio_feof(pb)) { - avio_read(pb, guid, 16); + if (avio_read(pb, guid, 16) != 16) + break; size = avio_rl64(pb); if (size <= 24 || size > INT64_MAX - 8) return AVERROR_INVALIDDATA; diff --git a/libavformat/wtvdec.c b/libavformat/wtvdec.c index 21c964986..c2fddc89b 100644 --- a/libavformat/wtvdec.c +++ b/libavformat/wtvdec.c @@ -878,7 +878,8 @@ static int parse_chunks(AVFormatContext *s, int mode, int64_t seekts, int *len_p AVStream *st = s->streams[stream_index]; uint8_t language[4]; avio_skip(pb, 12); - avio_read(pb, language, 3); + if (avio_read(pb, language, 3) != 3) + return AVERROR_INVALIDDATA; if (language[0]) { language[3] = 0; av_dict_set(&st->metadata, "language", language, 0); diff --git a/libavformat/xwma.c b/libavformat/xwma.c index b77c6ed60..d2333feb9 100644 --- a/libavformat/xwma.c +++ b/libavformat/xwma.c @@ -269,7 +269,7 @@ static int xwma_read_header(AVFormatContext *s) * an offset / timestamp pair. */ av_add_index_entry(st, - cur_pos + (i+1) * st->codecpar->block_align, /* pos */ + cur_pos + (i+1LL) * st->codecpar->block_align, /* pos */ dpds_table[i] / bytes_per_sample, /* timestamp */ st->codecpar->block_align, /* size */ 0, /* duration */ diff --git a/libavformat/yuv4mpegenc.c b/libavformat/yuv4mpegenc.c index 35397cbde..bcaf080d9 100644 --- a/libavformat/yuv4mpegenc.c +++ b/libavformat/yuv4mpegenc.c @@ -197,6 +197,9 @@ static int yuv4_write_packet(AVFormatContext *s, AVPacket *pkt) width = st->codecpar->width; height = st->codecpar->height; + if (frame->width != width || frame->height != height) + return AVERROR(EINVAL); + desc = av_pix_fmt_desc_get(st->codecpar->format); /* The following code presumes all planes to be non-interleaved. */ diff --git a/libavutil/aes.c b/libavutil/aes.c index 2f08fb416..f79a060b1 100644 --- a/libavutil/aes.c +++ b/libavutil/aes.c @@ -271,4 +271,3 @@ int av_aes_init(AVAES *a, const uint8_t *key, int key_bits, int decrypt) return 0; } - diff --git a/libavutil/bswap.h b/libavutil/bswap.h index f53e5768a..c1e6591ce 100644 --- a/libavutil/bswap.h +++ b/libavutil/bswap.h @@ -68,7 +68,7 @@ static av_always_inline av_const uint32_t av_bswap32(uint32_t x) #ifndef av_bswap64 static inline uint64_t av_const av_bswap64(uint64_t x) { - return (uint64_t)av_bswap32(x) << 32 | av_bswap32(x >> 32); + return (uint64_t)av_bswap32((uint32_t)x) << 32 | av_bswap32((uint32_t)(x >> 32)); } #endif diff --git a/libavutil/dovi_meta.h b/libavutil/dovi_meta.h index 5e8a1e43d..99af82c92 100644 --- a/libavutil/dovi_meta.h +++ b/libavutil/dovi_meta.h @@ -369,6 +369,10 @@ av_dovi_get_color(const AVDOVIMetadata *data) return (AVDOVIColorMetadata *)((uint8_t *) data + data->color_offset); } +/** + * Gets the specified Dolby Vision Display Management (DM) metadata + * @param index must be non negative and below data->num_ext_blocks + */ static av_always_inline AVDOVIDmData * av_dovi_get_ext(const AVDOVIMetadata *data, int index) { diff --git a/libavutil/eval.c b/libavutil/eval.c index 298925a6e..65eaa14bd 100644 --- a/libavutil/eval.c +++ b/libavutil/eval.c @@ -40,6 +40,8 @@ #include "avstring.h" #include "reverse.h" +#define MAX_DEPTH 100 + typedef struct Parser { const AVClass *class; int stack_index; @@ -176,6 +178,7 @@ struct AVExpr { struct AVExpr *param[3]; double *var; FFSFC64 *prng_state; + int depth; }; static double etime(double v) @@ -445,6 +448,14 @@ static int parse_primary(AVExpr **e, Parser *p) } p->s++; // ")" + for (int i = 0; i<3; i++) + if (d->param[i]) + d->depth = FFMAX(d->depth, d->param[i]->depth+1); + if (d->depth > MAX_DEPTH) { + av_expr_free(d); + return AVERROR(EINVAL); + } + d->type = e_func0; if (strmatch(next, "sinh" )) d->a.func0 = sinh; else if (strmatch(next, "cosh" )) d->a.func0 = cosh; @@ -529,6 +540,9 @@ static int parse_primary(AVExpr **e, Parser *p) static AVExpr *make_eval_expr(int type, int value, AVExpr *p0, AVExpr *p1) { + int depth = FFMAX(p0->depth, p1->depth) + 1; + if (depth > MAX_DEPTH) + return NULL; AVExpr *e = av_mallocz(sizeof(AVExpr)); if (!e) return NULL; @@ -536,6 +550,7 @@ static AVExpr *make_eval_expr(int type, int value, AVExpr *p0, AVExpr *p1) e->value =value ; e->param[0] =p0 ; e->param[1] =p1 ; + e->depth = depth; return e; } diff --git a/libavutil/hwcontext_cuda_internal.h b/libavutil/hwcontext_cuda_internal.h index d5633c58d..a989c4586 100644 --- a/libavutil/hwcontext_cuda_internal.h +++ b/libavutil/hwcontext_cuda_internal.h @@ -36,4 +36,3 @@ struct AVCUDADeviceContextInternal { }; #endif /* AVUTIL_HWCONTEXT_CUDA_INTERNAL_H */ - diff --git a/libavutil/hwcontext_d3d12va.c b/libavutil/hwcontext_d3d12va.c index 6507cf69c..339572679 100644 --- a/libavutil/hwcontext_d3d12va.c +++ b/libavutil/hwcontext_d3d12va.c @@ -660,7 +660,7 @@ static int d3d12va_device_create(AVHWDeviceContext *hwdev, const char *device, DXGI_ADAPTER_DESC desc; hr = IDXGIAdapter2_GetDesc(pAdapter, &desc); if (!FAILED(hr)) { - av_log(ctx, AV_LOG_INFO, "Using device %04x:%04x (%ls).\n", + av_log(hwdev, AV_LOG_INFO, "Using device %04x:%04x (%ls).\n", desc.VendorId, desc.DeviceId, desc.Description); } } @@ -668,7 +668,7 @@ static int d3d12va_device_create(AVHWDeviceContext *hwdev, const char *device, hr = priv->create_device((IUnknown *)pAdapter, D3D_FEATURE_LEVEL_12_0, &IID_ID3D12Device, (void **)&ctx->device); D3D12_OBJECT_RELEASE(pAdapter); if (FAILED(hr)) { - av_log(ctx, AV_LOG_ERROR, "Failed to create Direct 3D 12 device (%lx)\n", (long)hr); + av_log(hwdev, AV_LOG_ERROR, "Failed to create Direct 3D 12 device (%lx)\n", (long)hr); return AVERROR_UNKNOWN; } } diff --git a/libavutil/hwcontext_qsv.h b/libavutil/hwcontext_qsv.h index 35530e4e9..3c16a8ab9 100644 --- a/libavutil/hwcontext_qsv.h +++ b/libavutil/hwcontext_qsv.h @@ -84,4 +84,3 @@ typedef struct AVQSVFramesContext { } AVQSVFramesContext; #endif /* AVUTIL_HWCONTEXT_QSV_H */ - diff --git a/libavutil/samplefmt.h b/libavutil/samplefmt.h index 43a57a422..6e55d7114 100644 --- a/libavutil/samplefmt.h +++ b/libavutil/samplefmt.h @@ -122,8 +122,7 @@ enum AVSampleFormat av_get_planar_sample_fmt(enum AVSampleFormat sample_fmt); * @param sample_fmt the number of the sample format to print the * corresponding info string, or a negative value to print the * corresponding header. - * @return the pointer to the filled buffer or NULL if sample_fmt is - * unknown or in case of other errors + * @return the pointer to the filled buffer or NULL in case of other errors */ char *av_get_sample_fmt_string(char *buf, int buf_size, enum AVSampleFormat sample_fmt); diff --git a/libavutil/tests/blowfish.c b/libavutil/tests/blowfish.c index f4c9ced9b..0dd4d22c9 100644 --- a/libavutil/tests/blowfish.c +++ b/libavutil/tests/blowfish.c @@ -191,4 +191,3 @@ int main(void) return 0; } - diff --git a/libavutil/timecode.c b/libavutil/timecode.c index f454466f9..568a2160d 100644 --- a/libavutil/timecode.c +++ b/libavutil/timecode.c @@ -232,6 +232,7 @@ int av_timecode_init(AVTimecode *tc, AVRational rate, int flags, int frame_start int av_timecode_init_from_components(AVTimecode *tc, AVRational rate, int flags, int hh, int mm, int ss, int ff, void *log_ctx) { int ret; + int64_t s; memset(tc, 0, sizeof(*tc)); tc->flags = flags; @@ -242,7 +243,15 @@ int av_timecode_init_from_components(AVTimecode *tc, AVRational rate, int flags, if (ret < 0) return ret; - tc->start = (hh*3600 + mm*60 + ss) * tc->fps + ff; + s = hh*3600LL + mm*60LL + ss; + if (s != (int32_t)s) + return AVERROR(EINVAL); + + s = s * tc->fps + ff; + if (s != (int32_t)s) + return AVERROR(EINVAL); + tc->start = s; + if (tc->flags & AV_TIMECODE_FLAG_DROPFRAME) { /* adjust frame number */ int tmins = 60*hh + mm; tc->start -= (tc->fps / 30 * 2) * (tmins - tmins/10); diff --git a/libswresample/aarch64/resample.S b/libswresample/aarch64/resample.S index 6d9eaaeb2..89edd1ce6 100644 --- a/libswresample/aarch64/resample.S +++ b/libswresample/aarch64/resample.S @@ -30,7 +30,7 @@ function ff_resample_common_apply_filter_x4_float_neon, export=1 faddp v0.4s, v0.4s, v0.4s // pair adding of the 4x32-bit accumulated values faddp v0.4s, v0.4s, v0.4s // pair adding of the 4x32-bit accumulated values st1 {v0.s}[0], [x0], #4 // write accumulator - ret + ret endfunc function ff_resample_common_apply_filter_x8_float_neon, export=1 @@ -46,7 +46,7 @@ function ff_resample_common_apply_filter_x8_float_neon, export=1 faddp v0.4s, v0.4s, v0.4s // pair adding of the 4x32-bit accumulated values faddp v0.4s, v0.4s, v0.4s // pair adding of the 4x32-bit accumulated values st1 {v0.s}[0], [x0], #4 // write accumulator - ret + ret endfunc function ff_resample_common_apply_filter_x4_s16_neon, export=1 @@ -59,7 +59,7 @@ function ff_resample_common_apply_filter_x4_s16_neon, export=1 addp v0.4s, v0.4s, v0.4s // pair adding of the 4x32-bit accumulated values addp v0.4s, v0.4s, v0.4s // pair adding of the 4x32-bit accumulated values st1 {v0.s}[0], [x0], #4 // write accumulator - ret + ret endfunc function ff_resample_common_apply_filter_x8_s16_neon, export=1 @@ -73,5 +73,5 @@ function ff_resample_common_apply_filter_x8_s16_neon, export=1 addp v0.4s, v0.4s, v0.4s // pair adding of the 4x32-bit accumulated values addp v0.4s, v0.4s, v0.4s // pair adding of the 4x32-bit accumulated values st1 {v0.s}[0], [x0], #4 // write accumulator - ret + ret endfunc diff --git a/libswresample/rematrix.c b/libswresample/rematrix.c index b9bf4dcac..04ae58671 100644 --- a/libswresample/rematrix.c +++ b/libswresample/rematrix.c @@ -66,7 +66,10 @@ int swr_set_matrix(struct SwrContext *s, const double *matrix, int stride) { int nb_in, nb_out, in, out; - if (!s || s->in_convert) // s needs to be allocated but not initialized + if (!s || s->in_convert || // s needs to be allocated but not initialized + swri_check_chlayout(s, &s->user_in_chlayout , "input") || + swri_check_chlayout(s, &s->user_out_chlayout, "output") + ) return AVERROR(EINVAL); memset(s->matrix, 0, sizeof(s->matrix)); memset(s->matrix_flt, 0, sizeof(s->matrix_flt)); diff --git a/libswresample/resample_template.c b/libswresample/resample_template.c index 4c227b994..c6cc55e7a 100644 --- a/libswresample/resample_template.c +++ b/libswresample/resample_template.c @@ -25,6 +25,8 @@ * @author Michael Niedermayer */ +// FELEM2U, a variant of FELEM2 which does not produce undefined overflow + #if defined(TEMPLATE_RESAMPLE_DBL) # define RENAME(N) N ## _double @@ -32,6 +34,7 @@ # define DELEM double # define FELEM double # define FELEM2 double +# define FELEM2U double # define FOFFSET 0 # define OUT(d, v) d = v @@ -42,6 +45,7 @@ # define DELEM float # define FELEM float # define FELEM2 float +# define FELEM2U float # define FOFFSET 0 # define OUT(d, v) d = v @@ -52,6 +56,7 @@ # define DELEM int32_t # define FELEM int32_t # define FELEM2 int64_t +# define FELEM2U uint64_t # define FELEM_MAX INT32_MAX # define FELEM_MIN INT32_MIN # define FOFFSET (1<<(FILTER_SHIFT-1)) @@ -64,6 +69,7 @@ # define DELEM int16_t # define FELEM int16_t # define FELEM2 int32_t +# define FELEM2U uint32_t # define FELEML int64_t # define FELEM_MAX INT16_MAX # define FELEM_MIN INT16_MIN @@ -161,7 +167,7 @@ static int RENAME(resample_linear)(ResampleContext *c, for (dst_index = 0; dst_index < n; dst_index++) { FELEM *filter = ((FELEM *) c->filter_bank) + c->filter_alloc * index; - FELEM2 val = FOFFSET, v2 = FOFFSET; + FELEM2U val = FOFFSET, v2 = FOFFSET; int i; for (i = 0; i < c->filter_length; i++) { @@ -169,15 +175,15 @@ static int RENAME(resample_linear)(ResampleContext *c, v2 += src[sample_index + i] * (FELEM2)filter[i + c->filter_alloc]; } #ifdef FELEML - val += (v2 - val) * (FELEML) frac / c->src_incr; + val += (FELEM2)(v2 - val) * (FELEML) frac / c->src_incr; #else # if FILTER_SHIFT == 0 - val += (v2 - val) * inv_src_incr * frac; + val += (FELEM2)(v2 - val) * inv_src_incr * frac; # else - val += (v2 - val) / c->src_incr * frac; + val += (FELEM2)(v2 - val) / c->src_incr * frac; # endif #endif - OUT(dst[dst_index], val); + OUT(dst[dst_index], (FELEM2)val); frac += c->dst_incr_mod; index += c->dst_incr_div; @@ -205,6 +211,7 @@ static int RENAME(resample_linear)(ResampleContext *c, #undef DELEM #undef FELEM #undef FELEM2 +#undef FELEM2U #undef FELEML #undef FELEM_MAX #undef FELEM_MIN diff --git a/libswresample/soxr_resample.c b/libswresample/soxr_resample.c index 8181c749b..00d79878c 100644 --- a/libswresample/soxr_resample.c +++ b/libswresample/soxr_resample.c @@ -127,4 +127,3 @@ struct Resampler const swri_soxr_resampler={ create, destroy, process, flush, NULL /* set_compensation */, get_delay, invert_initial_buffer, get_out_samples }; - diff --git a/libswresample/swresample.c b/libswresample/swresample.c index 0a4e216f9..cb2238a4a 100644 --- a/libswresample/swresample.c +++ b/libswresample/swresample.c @@ -30,6 +30,20 @@ #define ALIGN 32 +int swri_check_chlayout(struct SwrContext *s, const AVChannelLayout *chl, const char *name) { + char l1[1024]; + int ret; + + if (!(ret = av_channel_layout_check(chl)) || chl->nb_channels > SWR_CH_MAX) { + if (ret) + av_channel_layout_describe(chl, l1, sizeof(l1)); + av_log(s, AV_LOG_WARNING, "%s channel layout \"%s\" is invalid or unsupported.\n", name, ret ? l1 : ""); + return AVERROR(EINVAL); + } + + return 0; +} + int swr_set_channel_mapping(struct SwrContext *s, const int *channel_map){ if(!s || s->in_convert) // s needs to be allocated but not initialized return AVERROR(EINVAL); @@ -54,6 +68,8 @@ int swr_alloc_set_opts2(struct SwrContext **ps, if ((ret = av_opt_set_chlayout(s, "ochl", out_ch_layout, 0)) < 0) goto fail; + if ((ret = swri_check_chlayout(s, out_ch_layout, "ochl")) < 0) + goto fail; if ((ret = av_opt_set_int(s, "osf", out_sample_fmt, 0)) < 0) goto fail; @@ -63,6 +79,8 @@ int swr_alloc_set_opts2(struct SwrContext **ps, if ((ret = av_opt_set_chlayout(s, "ichl", in_ch_layout, 0)) < 0) goto fail; + if ((ret = swri_check_chlayout(s, in_ch_layout, "ichl")) < 0) + goto fail; if ((ret = av_opt_set_int(s, "isf", in_sample_fmt, 0)) < 0) goto fail; @@ -164,19 +182,9 @@ av_cold int swr_init(struct SwrContext *s){ s->out.ch_count = s-> user_out_chlayout.nb_channels; s-> in.ch_count = s-> user_in_chlayout.nb_channels; - if (!(ret = av_channel_layout_check(&s->user_in_chlayout)) || s->user_in_chlayout.nb_channels > SWR_CH_MAX) { - if (ret) - av_channel_layout_describe(&s->user_in_chlayout, l1, sizeof(l1)); - av_log(s, AV_LOG_WARNING, "Input channel layout \"%s\" is invalid or unsupported.\n", ret ? l1 : ""); + if (swri_check_chlayout(s, &s->user_in_chlayout , "input") || + swri_check_chlayout(s, &s->user_out_chlayout, "output")) return AVERROR(EINVAL); - } - - if (!(ret = av_channel_layout_check(&s->user_out_chlayout)) || s->user_out_chlayout.nb_channels > SWR_CH_MAX) { - if (ret) - av_channel_layout_describe(&s->user_out_chlayout, l2, sizeof(l2)); - av_log(s, AV_LOG_WARNING, "Output channel layout \"%s\" is invalid or unsupported.\n", ret ? l2 : ""); - return AVERROR(EINVAL); - } ret = av_channel_layout_copy(&s->in_ch_layout, &s->user_in_chlayout); ret |= av_channel_layout_copy(&s->out_ch_layout, &s->user_out_chlayout); diff --git a/libswresample/swresample_frame.c b/libswresample/swresample_frame.c index 52e942f9c..1334f462a 100644 --- a/libswresample/swresample_frame.c +++ b/libswresample/swresample_frame.c @@ -172,4 +172,3 @@ int swr_convert_frame(SwrContext *s, return convert_frame(s, out, in); } - diff --git a/libswresample/swresample_internal.h b/libswresample/swresample_internal.h index 7e46b16fb..4aa4e20f2 100644 --- a/libswresample/swresample_internal.h +++ b/libswresample/swresample_internal.h @@ -187,6 +187,7 @@ struct SwrContext { av_warn_unused_result int swri_realloc_audio(AudioData *a, int count); +int swri_check_chlayout(struct SwrContext *s, const AVChannelLayout *chl, const char *name); void swri_noise_shaping_int16 (SwrContext *s, AudioData *dsts, const AudioData *srcs, const AudioData *noises, int count); void swri_noise_shaping_int32 (SwrContext *s, AudioData *dsts, const AudioData *srcs, const AudioData *noises, int count); diff --git a/libswresample/version.c b/libswresample/version.c index 40fbbabf9..06c3d6063 100644 --- a/libswresample/version.c +++ b/libswresample/version.c @@ -43,4 +43,3 @@ const char *swresample_license(void) #define LICENSE_PREFIX "libswresample license: " return &LICENSE_PREFIX FFMPEG_LICENSE[sizeof(LICENSE_PREFIX) - 1]; } - diff --git a/libswscale/aarch64/yuv2rgb_neon.S b/libswscale/aarch64/yuv2rgb_neon.S index cc7d8b58f..0797a6d5e 100644 --- a/libswscale/aarch64/yuv2rgb_neon.S +++ b/libswscale/aarch64/yuv2rgb_neon.S @@ -126,7 +126,7 @@ .endm .macro load_chroma_yuv422p - load_chroma_yuv420p + load_chroma_yuv420p .endm .macro increment_nv12 @@ -136,7 +136,7 @@ .endm .macro increment_nv21 - increment_nv12 + increment_nv12 .endm .macro increment_yuv420p @@ -182,7 +182,7 @@ function ff_\ifmt\()_to_\ofmt\()_neon, export=1 mov w8, w0 // w8 = width 2: movi v5.8h, #4, lsl #8 // 128 * (1<<3) - load_chroma_\ifmt + load_chroma_\ifmt sub v18.8h, v18.8h, v5.8h // U*(1<<3) - 128*(1<<3) sub v19.8h, v19.8h, v5.8h // V*(1<<3) - 128*(1<<3) sqdmulh v20.8h, v19.8h, v1.h[0] // V * v2r (R) @@ -237,11 +237,11 @@ function ff_\ifmt\()_to_\ofmt\()_neon, export=1 add x15, x15, w16, sxtw // dst2 += padding2 .endif add x4, x4, w5, sxtw // srcY += paddingY - increment_\ifmt + increment_\ifmt subs w1, w1, #1 // height -= 1 b.gt 1b mov w0, w9 - ret + ret endfunc .endm diff --git a/libswscale/gamma.c b/libswscale/gamma.c index 7c5534e1b..c62988002 100644 --- a/libswscale/gamma.c +++ b/libswscale/gamma.c @@ -70,4 +70,3 @@ int ff_init_gamma_convert(SwsFilterDescriptor *desc, SwsSlice * src, uint16_t *t return 0; } - diff --git a/libswscale/output.c b/libswscale/output.c index 1ddbee9b2..9194bba39 100644 --- a/libswscale/output.c +++ b/libswscale/output.c @@ -410,8 +410,10 @@ static void yuv2planeX_8_c(const int16_t *filter, int filterSize, for (i=0; i>19); } @@ -1062,8 +1064,8 @@ yuv2rgba64_X_c_template(SwsContext *c, const int16_t *lumFilter, int j; unsigned Y1 = -0x40000000; unsigned Y2 = -0x40000000; - int U = -(128 << 23); // 19 - int V = -(128 << 23); + unsigned U = -(128 << 23); // 19 + unsigned V = -(128 << 23); int R, G, B; for (j = 0; j < lumFilterSize; j++) { @@ -1093,8 +1095,8 @@ yuv2rgba64_X_c_template(SwsContext *c, const int16_t *lumFilter, Y1 += 0x10000; Y2 = (int)Y2 >> 14; Y2 += 0x10000; - U >>= 14; - V >>= 14; + U = (int)U >> 14; + V = (int)V >> 14; // 8 bits: 27 -> 17 bits, 16 bits: 31 - 14 = 17 bits Y1 -= c->yuv2rgb_y_offset; @@ -1204,7 +1206,7 @@ yuv2rgba64_1_c_template(SwsContext *c, const int32_t *buf0, { const int32_t *ubuf0 = ubuf[0], *vbuf0 = vbuf[0]; int i; - int A1 = 0xffff<<14, A2= 0xffff<<14; + SUINT A1 = 0xffff<<14, A2= 0xffff<<14; if (uvalpha < 2048) { for (i = 0; i < ((dstW + 1) >> 1); i++) { @@ -1222,8 +1224,8 @@ yuv2rgba64_1_c_template(SwsContext *c, const int32_t *buf0, Y2 += (1 << 13) - (1 << 29); if (hasAlpha) { - A1 = abuf0[i * 2 ] * (1 << 11); - A2 = abuf0[i * 2 + 1] * (1 << 11); + A1 = abuf0[i * 2 ] * (SUINT)(1 << 11); + A2 = abuf0[i * 2 + 1] * (SUINT)(1 << 11); A1 += 1 << 13; A2 += 1 << 13; @@ -2378,9 +2380,9 @@ yuv2gbrp16_full_X_c(SwsContext *c, const int16_t *lumFilter, G = V * c->yuv2rgb_v2g_coeff + U * c->yuv2rgb_u2g_coeff; B = U * c->yuv2rgb_u2b_coeff; - dest16[2][i] = av_clip_uintp2(((Y + R) >> 14) + (1<<15), 16); - dest16[0][i] = av_clip_uintp2(((Y + G) >> 14) + (1<<15), 16); - dest16[1][i] = av_clip_uintp2(((Y + B) >> 14) + (1<<15), 16); + dest16[2][i] = av_clip_uintp2(((Y + (int64_t)R) >> 14) + (1<<15), 16); + dest16[0][i] = av_clip_uintp2(((Y + (int64_t)G) >> 14) + (1<<15), 16); + dest16[1][i] = av_clip_uintp2(((Y + (int64_t)B) >> 14) + (1<<15), 16); if (hasAlpha) dest16[3][i] = av_clip_uintp2(A, 30) >> 14; diff --git a/libswscale/rgb2rgb_template.c b/libswscale/rgb2rgb_template.c index d4204153d..e671d3b15 100644 --- a/libswscale/rgb2rgb_template.c +++ b/libswscale/rgb2rgb_template.c @@ -466,11 +466,11 @@ static inline void yuvPlanartouyvy_c(const uint8_t *ysrc, const uint8_t *usrc, for (i = 0; i < chromWidth; i++) { #if HAVE_BIGENDIAN - *idst++ = (uc[0] << 24) + (yc[0] << 16) + + *idst++ = ((unsigned)uc[0] << 24) + (yc[0] << 16) + (vc[0] << 8) + (yc[1] << 0); #else *idst++ = uc[0] + (yc[0] << 8) + - (vc[0] << 16) + (yc[1] << 24); + (vc[0] << 16) + ((unsigned)yc[1] << 24); #endif yc += 2; uc++; diff --git a/libswscale/swscale_unscaled.c b/libswscale/swscale_unscaled.c index 45ea88218..587483d12 100644 --- a/libswscale/swscale_unscaled.c +++ b/libswscale/swscale_unscaled.c @@ -126,9 +126,13 @@ void ff_copyPlane(const uint8_t *src, int srcStride, int srcSliceY, int srcSliceH, int width, uint8_t *dst, int dstStride) { + if (!srcSliceH) + return; + av_assert0(srcSliceH > 0); + dst += dstStride * srcSliceY; if (dstStride == srcStride && srcStride > 0) { - memcpy(dst, src, srcSliceH * dstStride); + memcpy(dst, src, (srcSliceH - 1) * dstStride + width); } else { int i; for (i = 0; i < srcSliceH; i++) { diff --git a/libswscale/utils.c b/libswscale/utils.c index c3154d82c..2a61f15b3 100644 --- a/libswscale/utils.c +++ b/libswscale/utils.c @@ -311,7 +311,8 @@ int ff_shuffle_filter_coefficients(SwsContext *c, int *filterPos, if ((c->srcBpc == 8) && (c->dstBpc <= 14)) { int16_t *filterCopy = NULL; if (filterSize > 4) { - if (!FF_ALLOC_TYPED_ARRAY(filterCopy, dstW * filterSize)) + filterCopy = av_malloc_array(dstW, filterSize * sizeof(*filterCopy)); + if (!filterCopy) return AVERROR(ENOMEM); memcpy(filterCopy, filter, dstW * filterSize * sizeof(int16_t)); } @@ -500,6 +501,11 @@ static av_cold int initFilter(int16_t **outFilter, int32_t **filterPos, sizeFactor = param[0] != SWS_PARAM_DEFAULT ? ceil(2 * param[0]) : 6; av_assert0(sizeFactor > 0); + if (sizeFactor > 50) { + ret = AVERROR(EINVAL); + goto fail; + } + if (xInc <= 1 << 16) filterSize = 1 + sizeFactor; // upscale else @@ -508,7 +514,8 @@ static av_cold int initFilter(int16_t **outFilter, int32_t **filterPos, filterSize = FFMIN(filterSize, srcW - 2); filterSize = FFMAX(filterSize, 1); - if (!FF_ALLOC_TYPED_ARRAY(filter, dstW * filterSize)) + filter = av_malloc_array(dstW, filterSize * sizeof(*filter)); + if (!filter) goto nomem; xDstInSrc = ((dstPos*(int64_t)xInc)>>7) - ((srcPos*0x10000LL)>>7); for (i = 0; i < dstW; i++) { @@ -607,7 +614,8 @@ static av_cold int initFilter(int16_t **outFilter, int32_t **filterPos, if (dstFilter) filter2Size += dstFilter->length - 1; av_assert0(filter2Size > 0); - if (!FF_ALLOCZ_TYPED_ARRAY(filter2, dstW * filter2Size)) + filter2 = av_calloc(dstW, filter2Size * sizeof(*filter2)); + if (!filter2) goto nomem; for (i = 0; i < dstW; i++) { int j, k; @@ -775,7 +783,8 @@ static av_cold int initFilter(int16_t **outFilter, int32_t **filterPos, // Note the +1 is for the MMX scaler which reads over the end /* align at 16 for AltiVec (needed by hScale_altivec_real) */ - if (!FF_ALLOCZ_TYPED_ARRAY(*outFilter, *outFilterSize * (dstW + 3))) + *outFilter = av_calloc(dstW + 3, *outFilterSize * sizeof(**outFilter)); + if (!*outFilter) goto nomem; /* normalize & store in outFilter */ @@ -1410,8 +1419,8 @@ static av_cold int sws_init_single_context(SwsContext *c, SwsFilter *srcFilter, if (!srcFilter) srcFilter = &dummyFilter; - c->lumXInc = (((int64_t)srcW << 16) + (dstW >> 1)) / dstW; - c->lumYInc = (((int64_t)srcH << 16) + (dstH >> 1)) / dstH; + int64_t lumXInc = (((int64_t)srcW << 16) + (dstW >> 1)) / dstW; + int64_t lumYInc = (((int64_t)srcH << 16) + (dstH >> 1)) / dstH; c->dstFormatBpp = av_get_bits_per_pixel(desc_dst); c->srcFormatBpp = av_get_bits_per_pixel(desc_src); c->vRounder = 4 * 0x0001000100010001ULL; @@ -1582,8 +1591,8 @@ static av_cold int sws_init_single_context(SwsContext *c, SwsFilter *srcFilter, } else c->canMMXEXTBeUsed = 0; - c->chrXInc = (((int64_t)c->chrSrcW << 16) + (c->chrDstW >> 1)) / c->chrDstW; - c->chrYInc = (((int64_t)c->chrSrcH << 16) + (c->chrDstH >> 1)) / c->chrDstH; + int64_t chrXInc = (((int64_t)c->chrSrcW << 16) + (c->chrDstW >> 1)) / c->chrDstW; + int64_t chrYInc = (((int64_t)c->chrSrcH << 16) + (c->chrDstH >> 1)) / c->chrDstH; /* Match pixel 0 of the src to pixel 0 of dst and match pixel n-2 of src * to pixel n-2 of dst, but only for the FAST_BILINEAR mode otherwise do @@ -1594,15 +1603,26 @@ static av_cold int sws_init_single_context(SwsContext *c, SwsFilter *srcFilter, * some special code for the first and last pixel */ if (flags & SWS_FAST_BILINEAR) { if (c->canMMXEXTBeUsed) { - c->lumXInc += 20; - c->chrXInc += 20; + lumXInc += 20; + chrXInc += 20; } // we don't use the x86 asm scaler if MMX is available else if (INLINE_MMX(cpu_flags) && c->dstBpc <= 14) { - c->lumXInc = ((int64_t)(srcW - 2) << 16) / (dstW - 2) - 20; - c->chrXInc = ((int64_t)(c->chrSrcW - 2) << 16) / (c->chrDstW - 2) - 20; + lumXInc = ((int64_t)(srcW - 2) << 16) / (dstW - 2) - 20; + chrXInc = ((int64_t)(c->chrSrcW - 2) << 16) / (c->chrDstW - 2) - 20; } } + if (chrXInc < 10 || chrXInc > INT_MAX || + chrYInc < 10 || chrYInc > INT_MAX || + lumXInc < 10 || lumXInc > INT_MAX || + lumYInc < 10 || lumYInc > INT_MAX) + return AVERROR_PATCHWELCOME; + + c->lumXInc = lumXInc; + c->lumYInc = lumYInc; + c->chrXInc = chrXInc; + c->chrYInc = chrYInc; + // hardcoded for now c->gamma_value = 2.2; @@ -1886,13 +1906,15 @@ static av_cold int sws_init_single_context(SwsContext *c, SwsFilter *srcFilter, PPC_ALTIVEC(cpu_flags) ? 8 : have_neon(cpu_flags) ? 2 : 1; - if ((ret = initFilter(&c->vLumFilter, &c->vLumFilterPos, &c->vLumFilterSize, + ret = initFilter(&c->vLumFilter, &c->vLumFilterPos, &c->vLumFilterSize, c->lumYInc, srcH, dstH, filterAlign, (1 << 12), (flags & SWS_BICUBLIN) ? (flags | SWS_BICUBIC) : flags, cpu_flags, srcFilter->lumV, dstFilter->lumV, c->param, get_local_pos(c, 0, 0, 1), - get_local_pos(c, 0, 0, 1))) < 0) + get_local_pos(c, 0, 0, 1)); + int usecascade = (ret == RETCODE_USE_CASCADE); + if (ret < 0 && !usecascade) goto fail; if ((ret = initFilter(&c->vChrFilter, &c->vChrFilterPos, &c->vChrFilterSize, c->chrYInc, c->chrSrcH, c->chrDstH, @@ -1904,10 +1926,15 @@ static av_cold int sws_init_single_context(SwsContext *c, SwsFilter *srcFilter, get_local_pos(c, c->chrDstVSubSample, c->dst_v_chr_pos, 1))) < 0) goto fail; + if (usecascade) { + ret = RETCODE_USE_CASCADE; + goto fail; + } #if HAVE_ALTIVEC - if (!FF_ALLOC_TYPED_ARRAY(c->vYCoeffsBank, c->vLumFilterSize * c->dstH) || - !FF_ALLOC_TYPED_ARRAY(c->vCCoeffsBank, c->vChrFilterSize * c->chrDstH)) + c->vYCoeffsBank = av_malloc_array(c->dstH, c->vLumFilterSize * sizeof(*c->vYCoeffsBank)); + c->vCCoeffsBank = av_malloc_array(c->chrDstH, c->vChrFilterSize * sizeof(*c->vCCoeffsBank)); + if (c->vYCoeffsBank == NULL || c->vCCoeffsBank == NULL) goto nomem; for (i = 0; i < c->vLumFilterSize * c->dstH; i++) { diff --git a/libswscale/vscale.c b/libswscale/vscale.c index 5b3234198..7515a08f1 100644 --- a/libswscale/vscale.c +++ b/libswscale/vscale.c @@ -319,5 +319,3 @@ void ff_init_vscale_pfn(SwsContext *c, lumCtx->pfn.yuv2anyX = yuv2anyX; } } - - diff --git a/tests/extended.ffconcat b/tests/extended.ffconcat index c8afbcedb..5d6d8f790 100644 --- a/tests/extended.ffconcat +++ b/tests/extended.ffconcat @@ -111,4 +111,3 @@ outpoint 00:00.40 file %SRCFILE% inpoint 00:00.40 - diff --git a/tests/fate-run.sh b/tests/fate-run.sh index 309ab8513..9dc533f50 100755 --- a/tests/fate-run.sh +++ b/tests/fate-run.sh @@ -43,8 +43,17 @@ esac target_path(){ - test ${1} = ${1#/} && p=${target_path}/ - echo ${p}${1} + case ${1} in + [a-zA-Z]:/*) + echo ${1} + ;; + /*) + echo ${1} + ;; + *) + echo ${target_path}/${1} + ;; + esac } # $1=value1, $2=value2, $3=threshold diff --git a/tests/fate/ffmpeg.mak b/tests/fate/ffmpeg.mak index d9348ee83..e3b6ef978 100644 --- a/tests/fate/ffmpeg.mak +++ b/tests/fate/ffmpeg.mak @@ -128,6 +128,11 @@ fate-ffmpeg-fix_sub_duration_heartbeat: CMD = fmtstdout srt -fix_sub_duration \ -c:v mpeg2video -b:v 2M -g 30 -sc_threshold 1000000000 \ -c:s srt \ -f null - +# FIXME: disabling comparison against reference as after ffmpeg multithreading +# went in, this test started depending on how far the input side +# progressed compared to how quickly the output encoded packets, +# causing spurious failures on the CI. +fate-ffmpeg-fix_sub_duration_heartbeat: CMP = null # FIXME: the integer AAC decoder does not produce the same output on all platforms # so until that is fixed we use the volume filter to silence the data diff --git a/tests/fate/ffprobe.mak b/tests/fate/ffprobe.mak index 23c6d3550..f09e0ce3e 100644 --- a/tests/fate/ffprobe.mak +++ b/tests/fate/ffprobe.mak @@ -25,4 +25,3 @@ FATE_FFPROBE-$(call FILTERDEMDECENCMUX, AEVALSRC TESTSRC ARESAMPLE, FFMETADATA, += $(FFPROBE_TEST_FILE_TESTS-yes) fate-ffprobe: $(FATE_FFPROBE-yes) - diff --git a/tests/fate/lossless-audio.mak b/tests/fate/lossless-audio.mak index 7c5af885b..3d16aa8ca 100644 --- a/tests/fate/lossless-audio.mak +++ b/tests/fate/lossless-audio.mak @@ -36,4 +36,3 @@ FATE_SAMPLES_LOSSLESS_AUDIO += $(FATE_SAMPLES_LOSSLESS_AUDIO-yes) FATE_SAMPLES_FFMPEG += $(FATE_SAMPLES_LOSSLESS_AUDIO) fate-lossless-audio: $(FATE_SAMPLES_LOSSLESS_AUDIO) - diff --git a/tests/ref/fate/filter-bwdif-mode0 b/tests/ref/fate/filter-bwdif-mode0 index 23dcaee90..91b47dbe7 100644 --- a/tests/ref/fate/filter-bwdif-mode0 +++ b/tests/ref/fate/filter-bwdif-mode0 @@ -3,7 +3,7 @@ #codec_id 0: rawvideo #dimensions 0: 720x576 #sar 0: 16/15 -0, 9, 9, 1, 622080, 0xd435648a +0, 9, 9, 1, 622080, 0x3f25bfc2 0, 10, 10, 1, 622080, 0x62085455 0, 11, 11, 1, 622080, 0x60f943a0 0, 12, 12, 1, 622080, 0x5396f14a diff --git a/tests/ref/fate/filter-bwdif-mode1 b/tests/ref/fate/filter-bwdif-mode1 index e8db88c93..1e604646e 100644 --- a/tests/ref/fate/filter-bwdif-mode1 +++ b/tests/ref/fate/filter-bwdif-mode1 @@ -3,7 +3,7 @@ #codec_id 0: rawvideo #dimensions 0: 720x576 #sar 0: 16/15 -0, 18, 18, 1, 622080, 0xd435648a +0, 18, 18, 1, 622080, 0x3f25bfc2 0, 19, 19, 1, 622080, 0xef4617cc 0, 20, 20, 1, 622080, 0x62085455 0, 21, 21, 1, 622080, 0x5b5ae735 diff --git a/tests/ref/fate/filter-bwdif10 b/tests/ref/fate/filter-bwdif10 index 85ce54388..d97acea99 100644 --- a/tests/ref/fate/filter-bwdif10 +++ b/tests/ref/fate/filter-bwdif10 @@ -3,7 +3,7 @@ #codec_id 0: rawvideo #dimensions 0: 720x576 #sar 0: 16/15 -0, 9, 9, 1, 1244160, 0x57c21e2b +0, 9, 9, 1, 1244160, 0x4f0e6e1c 0, 10, 10, 1, 1244160, 0x57152296 0, 11, 11, 1, 1244160, 0x0074598b 0, 12, 12, 1, 1244160, 0x44537bb8 diff --git a/tests/ref/fate/mov-mp4-iamf-7_1_4-video-last b/tests/ref/fate/mov-mp4-iamf-7_1_4-video-last index 35e8b9b0a..ede4a4002 100644 --- a/tests/ref/fate/mov-mp4-iamf-7_1_4-video-last +++ b/tests/ref/fate/mov-mp4-iamf-7_1_4-video-last @@ -210,7 +210,7 @@ TAG:handler_name=SoundHandler TAG:vendor_id=[0][0][0][0] [STREAM] index=0 -id=0x1 +id=0x9 DISPOSITION:default=1 DISPOSITION:dub=0 DISPOSITION:original=0 @@ -233,7 +233,7 @@ DISPOSITION:multilayer=0 [/STREAM] [STREAM] index=1 -id=0x2 +id=0xa DISPOSITION:default=0 DISPOSITION:dub=0 DISPOSITION:original=0 @@ -256,7 +256,7 @@ DISPOSITION:multilayer=0 [/STREAM] [STREAM] index=2 -id=0x3 +id=0xb DISPOSITION:default=0 DISPOSITION:dub=0 DISPOSITION:original=0 @@ -279,7 +279,7 @@ DISPOSITION:multilayer=0 [/STREAM] [STREAM] index=3 -id=0x4 +id=0xc DISPOSITION:default=0 DISPOSITION:dub=0 DISPOSITION:original=0 @@ -302,7 +302,7 @@ DISPOSITION:multilayer=0 [/STREAM] [STREAM] index=4 -id=0x5 +id=0xd DISPOSITION:default=0 DISPOSITION:dub=0 DISPOSITION:original=0 @@ -325,7 +325,7 @@ DISPOSITION:multilayer=0 [/STREAM] [STREAM] index=5 -id=0x6 +id=0xe DISPOSITION:default=0 DISPOSITION:dub=0 DISPOSITION:original=0 @@ -348,7 +348,7 @@ DISPOSITION:multilayer=0 [/STREAM] [STREAM] index=6 -id=0x7 +id=0xf DISPOSITION:default=0 DISPOSITION:dub=0 DISPOSITION:original=0 @@ -468,7 +468,7 @@ TAG:handler_name=SoundHandler TAG:vendor_id=[0][0][0][0] [STREAM] index=0 -id=0x1 +id=0x9 DISPOSITION:default=1 DISPOSITION:dub=0 DISPOSITION:original=0 @@ -491,7 +491,7 @@ DISPOSITION:multilayer=0 [/STREAM] [STREAM] index=1 -id=0x2 +id=0xa DISPOSITION:default=0 DISPOSITION:dub=0 DISPOSITION:original=0 @@ -514,7 +514,7 @@ DISPOSITION:multilayer=0 [/STREAM] [STREAM] index=2 -id=0x3 +id=0xb DISPOSITION:default=0 DISPOSITION:dub=0 DISPOSITION:original=0 @@ -537,7 +537,7 @@ DISPOSITION:multilayer=0 [/STREAM] [STREAM] index=3 -id=0x4 +id=0xc DISPOSITION:default=0 DISPOSITION:dub=0 DISPOSITION:original=0 @@ -560,7 +560,7 @@ DISPOSITION:multilayer=0 [/STREAM] [STREAM] index=4 -id=0x5 +id=0xd DISPOSITION:default=0 DISPOSITION:dub=0 DISPOSITION:original=0 @@ -583,7 +583,7 @@ DISPOSITION:multilayer=0 [/STREAM] [STREAM] index=5 -id=0x6 +id=0xe DISPOSITION:default=0 DISPOSITION:dub=0 DISPOSITION:original=0 @@ -606,7 +606,7 @@ DISPOSITION:multilayer=0 [/STREAM] [STREAM] index=6 -id=0x7 +id=0xf DISPOSITION:default=0 DISPOSITION:dub=0 DISPOSITION:original=0 @@ -630,31 +630,31 @@ DISPOSITION:multilayer=0 [/STREAM_GROUP] [STREAM] index=0 -id=0x1 +id=0x9 [/STREAM] [STREAM] index=1 -id=0x2 +id=0xa [/STREAM] [STREAM] index=2 -id=0x3 +id=0xb [/STREAM] [STREAM] index=3 -id=0x4 +id=0xc [/STREAM] [STREAM] index=4 -id=0x5 +id=0xd [/STREAM] [STREAM] index=5 -id=0x6 +id=0xe [/STREAM] [STREAM] index=6 -id=0x7 +id=0xf [/STREAM] [STREAM] index=7 diff --git a/tests/simple1.ffconcat b/tests/simple1.ffconcat index c9299e0fa..6dcadcbf7 100644 --- a/tests/simple1.ffconcat +++ b/tests/simple1.ffconcat @@ -9,4 +9,3 @@ file %SRCFILE% inpoint 00:00.20 outpoint 00:00.40 file_packet_meta dummy 1 - diff --git a/tests/simple2.ffconcat b/tests/simple2.ffconcat index d1c1ee0c4..0cc3df233 100644 --- a/tests/simple2.ffconcat +++ b/tests/simple2.ffconcat @@ -18,4 +18,3 @@ inpoint 00:02.20 file %SRCFILE% inpoint 00:01.80 outpoint 00:02.00 - diff --git a/tools/check_arm_indent.sh b/tools/check_arm_indent.sh new file mode 100755 index 000000000..5becfe0ae --- /dev/null +++ b/tools/check_arm_indent.sh @@ -0,0 +1,55 @@ +#!/bin/sh +# +# Copyright (c) 2025 Martin Storsjo +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are met: +# +# 1. Redistributions of source code must retain the above copyright notice, this +# list of conditions and the following disclaimer. +# +# 2. Redistributions in binary form must reproduce the above copyright notice, +# this list of conditions and the following disclaimer in the documentation +# and/or other materials provided with the distribution. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +# DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR +# ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +# (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +# ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +# SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + + +cd $(dirname $0)/.. + +if [ "$1" = "--apply" ]; then + apply=1 +fi + +ret=0 + +for i in */aarch64/*.S */aarch64/*/*.S; do + case $i in + libavcodec/aarch64/h264idct_neon.S|libavcodec/aarch64/h26x/epel_neon.S|libavcodec/aarch64/h26x/qpel_neon.S|libavcodec/aarch64/vc1dsp_neon.S) + # Skip files with known (and tolerated) deviations from the tool. + continue + esac + ./tools/indent_arm_assembly.pl < "$i" > tmp.S || ret=$? + if ! git diff --quiet --no-index "$i" tmp.S; then + if [ -n "$apply" ]; then + mv tmp.S "$i" + else + git --no-pager diff --no-index "$i" tmp.S + fi + ret=1 + fi +done + +rm -f tmp.S + +exit $ret diff --git a/tools/indent_arm_assembly.pl b/tools/indent_arm_assembly.pl new file mode 100755 index 000000000..359c2bcf4 --- /dev/null +++ b/tools/indent_arm_assembly.pl @@ -0,0 +1,243 @@ +#!/usr/bin/env perl +# +# Copyright (c) 2025 Martin Storsjo +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are met: +# +# 1. Redistributions of source code must retain the above copyright notice, this +# list of conditions and the following disclaimer. +# +# 2. Redistributions in binary form must reproduce the above copyright notice, +# this list of conditions and the following disclaimer in the documentation +# and/or other materials provided with the distribution. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +# DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR +# ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +# (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +# ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +# SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + + +# A script for reformatting ARM/AArch64 assembly according to the following +# style: +# - Instructions start after 8 columns, operands start after 24 columns +# - Vector register layouts and modifiers like "uxtw" are written in lowercase +# - Optionally align operand columns vertically according to their +# maximum width (accommodating for e.g. x0 vs x10, or v0.8b vs v16.16b). +# +# The script can be executed as "indent_arm_assembly.pl file [outfile]". +# If no outfile is specified, the given file is overwritten in place. +# +# Alternatively, the if no file parameters are given, the script reads input +# code on stdin, and outputs the reformatted code on stdout. + +use strict; + +my $indent_operands = 0; +my $instr_indent = 8; +my $operand_indent = 24; +my $match_indent = 0; +my $file; +my $outfile; + +while (@ARGV) { + my $opt = shift; + + if ($opt eq "-operands") { + $indent_operands = 1; + } elsif ($opt eq "-indent") { + $instr_indent = shift; + } elsif ($opt eq "-operand-indent") { + $operand_indent = shift; + } elsif ($opt eq "-match-indent") { + $match_indent = 1; + } else { + if (!$file) { + $file = $opt; + } elsif (!$outfile) { + $outfile = $opt; + } else { + die "Unrecognized parameter $opt\n"; + } + } +} + +if ($operand_indent < $instr_indent) { + die "Can't indent operands to $operand_indent while indenting " . + "instructions to $instr_indent\n"; +} + +# Return a string consisting of n spaces +sub spaces { + my $n = $_[0]; + return " " x $n; +} + +sub indentcolumns { + my $input = $_[0]; + my $chars = $_[1]; + my @operands = split(/,/, $input); + my $num = @operands; + my $ret = ""; + for (my $i = 0; $i < $num; $i++) { + my $cur = $operands[$i]; + # Trim out leading/trailing whitespace + $cur =~ s/^\s+|\s+$//g; + $ret .= $cur; + if ($i + 1 < $num) { + # If we have a following operand, add a comma and whitespace to + # align the next operand. + my $next = $operands[$i+1]; + my $len = length($cur); + if ($len > $chars) { + # If this operand was too wide for the intended column width, + # don't try to realign the line at all, just return the input + # untouched. + return $input; + } + my $pad = $chars - $len; + if ($next =~ /[su]xt[bhw]|[la]s[lr]/) { + # If the next item isn't a regular operand, but a modifier, + # don't try to align that. E.g. "add x0, x0, w1, uxtw #1". + $pad = 0; + } + $ret .= "," . spaces(1 + $pad); + } + } + return $ret; +} + +# Realign the operands part of an instruction line, making each operand +# take up the maximum width for that kind of operand. +sub columns { + my $rest = $_[0]; + if ($rest !~ /,/) { + # No commas, no operands to split and align + return $rest; + } + if ($rest =~ /{|[^\w]\[/) { + # Check for instructions that use register ranges, like {v0.8b,v1.8b} + # or mem address operands, like "ldr x0, [sp]" - we skip trying to + # realign these. + return $rest; + } + if ($rest =~ /v[0-9]+\.[0-9]+[bhsd]/) { + # If we have references to aarch64 style vector registers, like + # v0.8b, then align all operands to the maximum width of such + # operands - v16.16b. + # + # TODO: Ideally, we'd handle mixed operand types individually. + return indentcolumns($rest, 7); + } + # Indent operands according to the maximum width of regular registers, + # like x10. + return indentcolumns($rest, 3); +} + +my $in; +my $out; +my $tempfile; + +if ($file) { + open(INPUT, "$file") or die "Unable to open $file: $!"; + $in = *INPUT; + if ($outfile) { + open(OUTPUT, ">$outfile") or die "Unable to open $outfile: $!"; + } else { + $tempfile = "$file.tmp"; + open(OUTPUT, ">$tempfile") or die "Unable to open $tempfile: $!"; + } + $out = *OUTPUT; +} else { + $in = *STDIN; + $out = *STDOUT; +} + +while (<$in>) { + # Trim off trailing whitespace. + chomp; + if (/^([\.\w\d]+:)?(\s+)([\w\\][\w\\\.]*)(?:(\s+)(.*)|$)/) { + my $label = $1; + my $indent = $2; + my $instr = $3; + my $origspace = $4; + my $rest = $5; + + my $orig_operand_indent = length($label) + length($indent) + + length($instr) + length($origspace); + + if ($indent_operands) { + $rest = columns($rest); + } + + my $size = $instr_indent; + if ($match_indent) { + # Try to check the current attempted indent size and normalize + # to it; match existing ident sizes of 4, 8, 10 and 12 columns. + my $cur_indent = length($label) + length($indent); + if ($cur_indent >= 3 && $cur_indent <= 5) { + $size = 4; + } elsif ($cur_indent >= 7 && $cur_indent <= 9) { + $size = 8; + } elsif ($cur_indent == 10 || $cur_indent == 12) { + $size = $cur_indent; + } + } + if (length($label) >= $size) { + # Not enough space for the label; just add a space between the label + # and the instruction. + $indent = " "; + } else { + $indent = spaces($size - length($label)); + } + + my $instr_end = length($label) + length($indent) + length($instr); + $size = $operand_indent - $instr_end; + if ($match_indent) { + # Check how the operands currently seem to be indented. + my $cur_indent = $orig_operand_indent; + if ($cur_indent >= 11 && $cur_indent <= 13) { + $size = 12; + } elsif ($cur_indent >= 14 && $cur_indent <= 17) { + $size = 16; + } elsif ($cur_indent >= 18 && $cur_indent <= 22) { + $size = 20; + } elsif ($cur_indent >= 23 && $cur_indent <= 27) { + $size = 24; + } + $size -= $instr_end; + } + my $operand_space = " "; + if ($size > 0) { + $operand_space = spaces($size); + } + + # Lowercase the aarch64 vector layout description, .8B -> .8b + $rest =~ s/(\.[84216]*[BHSD])/lc($1)/ge; + # Lowercase modifiers like "uxtw" or "lsl" + $rest =~ s/([SU]XT[BWH]|[LA]S[LR])/lc($1)/ge; + + # Reassemble the line + if ($rest eq "") { + $_ = $label . $indent . $instr; + } else { + $_ = $label . $indent . $instr . $operand_space . $rest; + } + } + print $out $_ . "\n"; +} + +if ($file) { + close(INPUT); + close(OUTPUT); +} +if ($tempfile) { + rename($tempfile, $file); +}