From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from ffbox0-bg.ffmpeg.org (ffbox0-bg.ffmpeg.org [79.124.17.100]) by master.gitmailbox.com (Postfix) with ESMTPS id 0A66E4AE97 for ; Thu, 28 Aug 2025 20:24:24 +0000 (UTC) Authentication-Results: ffbox; dkim=fail (body hash mismatch (got b'EwSnXc5KbyyqnZRtNONeBjNFhn5ktN5JB/iDkNB6r0o=', expected b'uBfpDLXLzWqlyt/txCx4l/2H0RgB7UO/CuJxcRAJNEY=')) header.d=ffmpeg.org header.i=@ffmpeg.org header.a=rsa-sha256 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=ffmpeg.org; i=@ffmpeg.org; q=dns/txt; s=mail; t=1756412564; h=mime-version : to : message-id : reply-to : subject : list-id : list-archive : list-archive : list-help : list-owner : list-post : list-subscribe : list-unsubscribe : from : cc : content-type : content-transfer-encoding : from; bh=EwSnXc5KbyyqnZRtNONeBjNFhn5ktN5JB/iDkNB6r0o=; b=IliS5fObQoo7/XkpKacNWftPwvNxURaXWYQ9hlW7/u/Erw2ts+51aIdnuHfPNxqPGCvgq PdhY8WzYsf5ylx+Ba33TfgQ5i1Z3PGFe/vyPTo1Kxb/R5/ddHIBHCH2GntMueEBTHAgV2ut XFhryIsldQaQySl9Z5LwmGBy5H3ZbpW4Ovsp5z8QmYtu3kVIh9Dw5qz/N1fmesdC8wudyPU Y1y8ff9/PWRZ3oB0CL7Hfx4xet2yLSStTbpxumuOy0LarTWTJp4JllXTdJk5nJ97TNnmGCL wlPftiRb8aogu+NOOn4/44Ntz8+khM9/lJP9a+DfVnEToL6QzAcv/NeXUqDQ== Received: from [172.19.0.4] (unknown [172.19.0.4]) by ffbox0-bg.ffmpeg.org (Postfix) with ESMTP id DADBF68E7B4; Thu, 28 Aug 2025 23:22:44 +0300 (EEST) ARC-Seal: i=1; cv=none; a=rsa-sha256; d=ffmpeg.org; s=arc; t=1756412543; b=cWmiNrBPFowgoSJNummCITFyxaQwvvEzjZ1C6aICbeRplQKe9mCDsrFvMkvTqHLNRhHwI JnOheaFjutk0BKy0yBSDqfjw9Sin0K97yQQF7mikswKaVOWHidon6rmIiLKqBUYE9HRs6Yr fv7ryYrtm7SXNOnt7AQHPk7HULAzUpszDHGrmWoZ9uW45/OW4bgf3LEr1r52leP2mMA7x5Z zbFspRg2KjgB2zE2TIlOMGkneaSvJdZo4Dor6iU2NfU5lcPmcRJX1HHA22MbNwmsEc5b0hA mZdKIJnkjTlb5/zfU8VrYv6mnMhk5o9BkPB4INGlwb0xtQpqt61klD+gdf6g== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=ffmpeg.org; s=arc; t=1756412543; h=from : sender : reply-to : subject : date : message-id : to : cc : mime-version : content-type : content-transfer-encoding : content-id : content-description : resent-date : resent-from : resent-sender : resent-to : resent-cc : resent-message-id : in-reply-to : references : list-id : list-help : list-unsubscribe : list-subscribe : list-post : list-owner : list-archive; bh=+I+qKXywTWS/HxLMXnWdWZOUv0RDzoc9bxcn4sf6lzc=; b=Dy30EhMfY7YrEcicINmqOfdy7NxacL66GYtt5mZoFmFkAFaRJRPkKchXfb370o7kGGMqB YIppiSCrb0C/hfxUEjFVCpddhtYBGc+t8v/Ty2meDwmn9GeJzbSefeCc1NsjWa5qS5SSYya PjrxvMjWjFLSZP8sfkhFYjC8kE3qW6DcK46PQ2n093cCJWL9i/Pj1E7Y4tz8NGBYw6p/cSg PaQ/PLeStJbP2X8KjjvdqU6QpKZWLRi0MtMD9JJMaz+Cr5wZZXCYaOTMnKOqVJc6eoOdCbo zqC1ldCTu1VQ8IAYIySPpCwJXrJQpDG4O6w1I1mbnIHzDGdSXq2s7FdA91nQ== ARC-Authentication-Results: i=1; ffmpeg.org; dkim=pass header.d=ffmpeg.org header.i=@ffmpeg.org; arc=none; dmarc=none Authentication-Results: ffmpeg.org; dkim=pass header.d=ffmpeg.org header.i=@ffmpeg.org; arc=none (Message is not ARC signed); dmarc=none DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=ffmpeg.org; i=@ffmpeg.org; q=dns/txt; s=mail; t=1756412532; h=content-type : mime-version : content-transfer-encoding : from : to : reply-to : subject : from; bh=uBfpDLXLzWqlyt/txCx4l/2H0RgB7UO/CuJxcRAJNEY=; b=OwVC3VMgsxTZ7yZ+ahcEULojaV6iHGDZ1/WV/nI1qPw+O8enCE1mBLANzXLEK3E0vgaAd NVYH4KX1FnvF4ErXlOlSiLmZpeTeTeDi7mTDNPOmpJ4JxXR5yML7fN+POuDPjDhRkYIjiGk znFK1v+ultm96H2Da1c+1j4N34vVTjuz74lS3qWlbNmrzhXP4CdtrUUCtwVcGKwITERYh3S i8X/3rxcjBCR/RKZ2dWuMJ58mKZzw9hmaw3WPSGVylJubEp8IGhBGo4DjQ4imtHwU/3Ocsy kpctAZRBkHTMFBr6Tvb6SjDddidk/hkmSbNyDx9wIel13naeXGA4rBUjCkJQ== Received: from 5d8f51c41678 (code.ffmpeg.org [188.245.149.3]) by ffbox0-bg.ffmpeg.org (Postfix) with ESMTPS id B402468E6DF for ; Thu, 28 Aug 2025 23:22:12 +0300 (EEST) MIME-Version: 1.0 To: ffmpeg-devel@ffmpeg.org Message-ID: <175641253306.25.6726955788995795685@463a07221176> Message-ID-Hash: D26FN6JJB2NWHXQY5CDZHBGPJKHLWKOO X-Message-ID-Hash: D26FN6JJB2NWHXQY5CDZHBGPJKHLWKOO X-MailFrom: code@ffmpeg.org X-Mailman-Rule-Misses: dmarc-mitigation; no-senders; approved; loop; banned-address; header-match-ffmpeg-devel.ffmpeg.org-0; header-match-ffmpeg-devel.ffmpeg.org-1; header-match-ffmpeg-devel.ffmpeg.org-2; header-match-ffmpeg-devel.ffmpeg.org-3; emergency; member-moderation; nonmember-moderation; administrivia; implicit-dest; max-recipients; max-size; news-moderation; no-subject; digests; suspicious-header X-Mailman-Version: 3.3.10 Precedence: list Reply-To: FFmpeg development discussions and patches Subject: [FFmpeg-devel] [PATCH] Remove path length limits from various places using av_get_frame_filename() (PR #20363) List-Id: FFmpeg development discussions and patches Archived-At: Archived-At: List-Archive: List-Archive: List-Help: List-Owner: List-Post: List-Subscribe: List-Unsubscribe: From: Marton Balint via ffmpeg-devel Cc: Marton Balint Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: 7bit Archived-At: List-Archive: List-Post: PR #20363 opened by Marton Balint (cus) URL: https://code.ffmpeg.org/FFmpeg/FFmpeg/pulls/20363 Patch URL: https://code.ffmpeg.org/FFmpeg/FFmpeg/pulls/20363.patch >>From a748e8be26e37b5e185b5e49df54d89d39e64df8 Mon Sep 17 00:00:00 2001 From: Marton Balint Date: Wed, 27 Aug 2025 08:36:39 +0200 Subject: [PATCH 1/7] avformat/utils: add AV_FRAME_FILENAME_FLAGS_IGNORE_TRUNCATION flag Signed-off-by: Marton Balint --- doc/APIchanges | 3 +++ libavformat/avformat.h | 3 ++- libavformat/utils.c | 2 +- libavformat/version.h | 2 +- 4 files changed, 7 insertions(+), 3 deletions(-) diff --git a/doc/APIchanges b/doc/APIchanges index 5d4fb8d127..92d290677b 100644 --- a/doc/APIchanges +++ b/doc/APIchanges @@ -2,6 +2,9 @@ The last version increases of all libraries were on 2025-03-28 API changes, most recent first: +2025-09-xx - xxxxxxxx - lavc 62.4.102 - avformat.h + Add AV_FRAME_FILENAME_FLAGS_IGNORE_TRUNCATION + 2025-08-xx - xxxxxxxx - lavc 62.13.101 - exif.h Add AV_EXIF_FLAG_RECURSIVE diff --git a/libavformat/avformat.h b/libavformat/avformat.h index be6e532387..a7446546e5 100644 --- a/libavformat/avformat.h +++ b/libavformat/avformat.h @@ -2819,7 +2819,8 @@ void av_dump_format(AVFormatContext *ic, int is_output); -#define AV_FRAME_FILENAME_FLAGS_MULTIPLE 1 ///< Allow multiple %d +#define AV_FRAME_FILENAME_FLAGS_MULTIPLE 1 ///< Allow multiple %d +#define AV_FRAME_FILENAME_FLAGS_IGNORE_TRUNCATION 2 ///< Ignore truncated output instead of returning an error /** * Return in 'buf' the path with '%d' replaced by a number. diff --git a/libavformat/utils.c b/libavformat/utils.c index 8a249ad85a..9b29ae26d0 100644 --- a/libavformat/utils.c +++ b/libavformat/utils.c @@ -327,7 +327,7 @@ addchar: } if (!percentd_found) goto fail; - if (!av_bprint_is_complete(buf)) + if (!(flags & AV_FRAME_FILENAME_FLAGS_IGNORE_TRUNCATION) && !av_bprint_is_complete(buf)) return AVERROR(ENOMEM); return 0; fail: diff --git a/libavformat/version.h b/libavformat/version.h index cc56b7cf5c..858a94cc5d 100644 --- a/libavformat/version.h +++ b/libavformat/version.h @@ -32,7 +32,7 @@ #include "version_major.h" #define LIBAVFORMAT_VERSION_MINOR 4 -#define LIBAVFORMAT_VERSION_MICRO 101 +#define LIBAVFORMAT_VERSION_MICRO 102 #define LIBAVFORMAT_VERSION_INT AV_VERSION_INT(LIBAVFORMAT_VERSION_MAJOR, \ LIBAVFORMAT_VERSION_MINOR, \ -- 2.49.1 >>From fd409149188613e5e517376150c90aca03d32be9 Mon Sep 17 00:00:00 2001 From: Marton Balint Date: Thu, 14 Aug 2025 23:49:34 +0200 Subject: [PATCH 2/7] avformat/utils: support arbitrary path lengths for av_filename_number_test Signed-off-by: Marton Balint --- libavformat/utils.c | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/libavformat/utils.c b/libavformat/utils.c index 9b29ae26d0..3573aa918e 100644 --- a/libavformat/utils.c +++ b/libavformat/utils.c @@ -116,9 +116,12 @@ int av_append_packet(AVIOContext *s, AVPacket *pkt, int size) int av_filename_number_test(const char *filename) { - char buf[1024]; - return filename && - (av_get_frame_filename(buf, sizeof(buf), filename, 1) >= 0); + AVBPrint bp; + + if (!filename) + return 0; + av_bprint_init(&bp, 0, AV_BPRINT_SIZE_COUNT_ONLY); + return (ff_bprint_get_frame_filename(&bp, filename, 1, AV_FRAME_FILENAME_FLAGS_IGNORE_TRUNCATION) >= 0); } /**********************************************************/ -- 2.49.1 >>From e1f67590752b501623d0b40422d29dd74dd95c59 Mon Sep 17 00:00:00 2001 From: Marton Balint Date: Sun, 17 Aug 2025 20:39:09 +0200 Subject: [PATCH 3/7] avformat/segment: support arbitrary path lengths Signed-off-by: Marton Balint --- libavformat/segment.c | 36 +++++++++++++++++++++++------------- 1 file changed, 23 insertions(+), 13 deletions(-) diff --git a/libavformat/segment.c b/libavformat/segment.c index 05383de841..2c7ba0e776 100644 --- a/libavformat/segment.c +++ b/libavformat/segment.c @@ -38,6 +38,7 @@ #include "libavutil/mem.h" #include "libavutil/opt.h" #include "libavutil/avstring.h" +#include "libavutil/bprint.h" #include "libavutil/parseutils.h" #include "libavutil/mathematics.h" #include "libavutil/time.h" @@ -122,7 +123,7 @@ typedef struct SegmentContext { int write_empty; int use_rename; - char temp_list_filename[1024]; + char *temp_list_filename; SegmentListEntry cur_entry; SegmentListEntry *segment_list_entries; @@ -191,9 +192,10 @@ static int set_segment_filename(AVFormatContext *s) AVFormatContext *oc = seg->avf; size_t size; int ret; - char buf[1024]; + AVBPrint filename; char *new_name; + av_bprint_init(&filename, 0, AV_BPRINT_SIZE_UNLIMITED); if (seg->segment_idx_wrap) seg->segment_idx %= seg->segment_idx_wrap; if (seg->use_strftime) { @@ -201,18 +203,22 @@ static int set_segment_filename(AVFormatContext *s) struct tm *tm, tmpbuf; time(&now0); tm = localtime_r(&now0, &tmpbuf); - if (!strftime(buf, sizeof(buf), s->url, tm)) { - av_log(oc, AV_LOG_ERROR, "Could not get segment filename with strftime\n"); - return AVERROR(EINVAL); + av_bprint_strftime(&filename, s->url, tm); + if (!av_bprint_is_complete(&filename)) { + av_bprint_finalize(&filename, NULL); + return AVERROR(ENOMEM); + } + } else { + ret = ff_bprint_get_frame_filename(&filename, s->url, seg->segment_idx, 0); + if (ret < 0) { + av_bprint_finalize(&filename, NULL); + av_log(oc, AV_LOG_ERROR, "Invalid segment filename template '%s'\n", s->url); + return ret; } - } else if (av_get_frame_filename(buf, sizeof(buf), - s->url, seg->segment_idx) < 0) { - av_log(oc, AV_LOG_ERROR, "Invalid segment filename template '%s'\n", s->url); - return AVERROR(EINVAL); } - new_name = av_strdup(buf); - if (!new_name) - return AVERROR(ENOMEM); + ret = av_bprint_finalize(&filename, &new_name); + if (ret < 0) + return ret; ff_format_set_url(oc, new_name); /* copy modified name in list entry */ @@ -279,7 +285,10 @@ static int segment_list_open(AVFormatContext *s) SegmentContext *seg = s->priv_data; int ret; - snprintf(seg->temp_list_filename, sizeof(seg->temp_list_filename), seg->use_rename ? "%s.tmp" : "%s", seg->list); + av_freep(&seg->temp_list_filename); + seg->temp_list_filename = av_asprintf(seg->use_rename ? "%s.tmp" : "%s", seg->list); + if (!seg->temp_list_filename) + return AVERROR(ENOMEM); ret = s->io_open(s, &seg->list_pb, seg->temp_list_filename, AVIO_FLAG_WRITE, NULL); if (ret < 0) { av_log(s, AV_LOG_ERROR, "Failed to open segment list '%s'\n", seg->list); @@ -659,6 +668,7 @@ static void seg_free(AVFormatContext *s) av_freep(&seg->times); av_freep(&seg->frames); av_freep(&seg->cur_entry.filename); + av_freep(&seg->temp_list_filename); cur = seg->segment_list_entries; while (cur) { -- 2.49.1 >>From ea2e216af8083d280062e270e334adf2b8079567 Mon Sep 17 00:00:00 2001 From: Marton Balint Date: Mon, 18 Aug 2025 00:02:22 +0200 Subject: [PATCH 4/7] avformat/webm_chunk: support for arbitrary path lengths Signed-off-by: Marton Balint --- libavformat/webm_chunk.c | 22 ++++++++++------------ 1 file changed, 10 insertions(+), 12 deletions(-) diff --git a/libavformat/webm_chunk.c b/libavformat/webm_chunk.c index 255b8697c5..57329f1788 100644 --- a/libavformat/webm_chunk.c +++ b/libavformat/webm_chunk.c @@ -30,13 +30,12 @@ #include "internal.h" #include "mux.h" +#include "libavutil/bprint.h" #include "libavutil/log.h" #include "libavutil/mem.h" #include "libavutil/opt.h" #include "libavutil/mathematics.h" -#define MAX_FILENAME_SIZE 1024 - typedef struct WebMChunkContext { const AVClass *class; char *header_filename; @@ -133,16 +132,13 @@ fail: return 0; } -static int get_chunk_filename(AVFormatContext *s, char filename[MAX_FILENAME_SIZE]) +static int get_chunk_filename(AVFormatContext *s, AVBPrint *filename) { WebMChunkContext *wc = s->priv_data; - if (!filename) { - return AVERROR(EINVAL); - } - if (av_get_frame_filename(filename, MAX_FILENAME_SIZE, - s->url, wc->chunk_index - 1) < 0) { + int ret = ff_bprint_get_frame_filename(filename, s->url, wc->chunk_index - 1, 0); + if (ret < 0) { av_log(s, AV_LOG_ERROR, "Invalid chunk filename template '%s'\n", s->url); - return AVERROR(EINVAL); + return ret; } return 0; } @@ -185,7 +181,7 @@ static int chunk_end(AVFormatContext *s, int flush) int buffer_size; uint8_t *buffer; AVIOContext *pb; - char filename[MAX_FILENAME_SIZE]; + AVBPrint filename; AVDictionary *options = NULL; if (!oc->pb) @@ -196,19 +192,21 @@ static int chunk_end(AVFormatContext *s, int flush) av_write_frame(oc, NULL); buffer_size = avio_close_dyn_buf(oc->pb, &buffer); oc->pb = NULL; - ret = get_chunk_filename(s, filename); + av_bprint_init(&filename, 0, AV_BPRINT_SIZE_UNLIMITED); + ret = get_chunk_filename(s, &filename); if (ret < 0) goto fail; if (wc->http_method) if ((ret = av_dict_set(&options, "method", wc->http_method, 0)) < 0) goto fail; - ret = s->io_open(s, &pb, filename, AVIO_FLAG_WRITE, &options); + ret = s->io_open(s, &pb, filename.str, AVIO_FLAG_WRITE, &options); av_dict_free(&options); if (ret < 0) goto fail; avio_write(pb, buffer, buffer_size); ff_format_io_close(s, &pb); fail: + av_bprint_finalize(&filename, NULL); av_free(buffer); return (ret < 0) ? ret : 0; } -- 2.49.1 >>From fe9afd329f8a66c777dcb539d065348d7e43f584 Mon Sep 17 00:00:00 2001 From: Marton Balint Date: Wed, 13 Aug 2025 22:37:11 +0200 Subject: [PATCH 5/7] avformat/img2dec: do not use av_get_frame_filename result buffer if the call fails We have no way of knowing if the string was fully processed or got truncated because of a parse error so it is better to use the original path if finding an image sequence fails. We do this by explicitly falling back to the PT_NONE mode if the provided filename is not a valid pattern but the file exists or if the IO context is already open. This also means that filenames no longer need to be escaped even in sequence mode if an invalid sequence (a sequence without %d) is provided, so a command line such as ffmpeg -f image2 -i "100%.jpg" will just work, but "100%%.jpg" will no longer work. Signed-off-by: Marton Balint --- libavformat/img2dec.c | 26 +++++++++++++------------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/libavformat/img2dec.c b/libavformat/img2dec.c index a3f4ef14fa..3170132b08 100644 --- a/libavformat/img2dec.c +++ b/libavformat/img2dec.c @@ -93,7 +93,7 @@ static int infer_size(int *width_ptr, int *height_ptr, int size) * @param start_index minimum accepted value for the first index in the range * @return -1 if no image file could be found */ -static int find_image_range(AVIOContext *pb, int *pfirst_index, int *plast_index, +static int find_image_range(int *pfirst_index, int *plast_index, const char *path, int start_index, int start_index_range) { char buf[1024]; @@ -101,13 +101,8 @@ static int find_image_range(AVIOContext *pb, int *pfirst_index, int *plast_index /* find the first image */ for (first_index = start_index; first_index < start_index + start_index_range; first_index++) { - if (av_get_frame_filename(buf, sizeof(buf), path, first_index) < 0) { - *pfirst_index = - *plast_index = 1; - if (pb || avio_check(buf, AVIO_FLAG_READ) > 0) - return 0; + if (av_get_frame_filename(buf, sizeof(buf), path, first_index) < 0) return -1; - } if (avio_check(buf, AVIO_FLAG_READ) > 0) break; } @@ -222,12 +217,17 @@ int ff_img_read_header(AVFormatContext *s1) s->pattern_type = PT_SEQUENCE; } if (s->pattern_type == PT_SEQUENCE) { - if (find_image_range(s1->pb, &first_index, &last_index, s->path, + if (find_image_range(&first_index, &last_index, s->path, s->start_number, s->start_number_range) < 0) { - av_log(s1, AV_LOG_ERROR, - "Could find no file with path '%s' and index in the range %d-%d\n", - s->path, s->start_number, s->start_number + s->start_number_range - 1); - return AVERROR(ENOENT); + if (s1->pb || avio_check(s->path, AVIO_FLAG_READ) > 0) { + // Fallback to normal mode + s->pattern_type = PT_NONE; + } else { + av_log(s1, AV_LOG_ERROR, + "Could find no file or sequence with path '%s' and index in the range %d-%d\n", + s->path, s->start_number, s->start_number + s->start_number_range - 1); + return AVERROR(ENOENT); + } } } else if (s->pattern_type == PT_GLOB) { #if HAVE_GLOB @@ -378,7 +378,7 @@ int ff_img_read_packet(AVFormatContext *s1, AVPacket *pkt) } else { if (av_get_frame_filename(filename_bytes, sizeof(filename_bytes), s->path, - s->img_number) < 0 && s->img_number > 1) + s->img_number) < 0) return AVERROR(EIO); } for (i = 0; i < 3; i++) { -- 2.49.1 >>From bf4edbcb0ae8377e846b9bfb494192bb9ac93cfb Mon Sep 17 00:00:00 2001 From: Marton Balint Date: Sun, 17 Aug 2025 23:08:26 +0200 Subject: [PATCH 6/7] avformat/img2dec: remove path limits from find_image_range Signed-off-by: Marton Balint --- libavformat/img2dec.c | 35 ++++++++++++++++++++++------------- 1 file changed, 22 insertions(+), 13 deletions(-) diff --git a/libavformat/img2dec.c b/libavformat/img2dec.c index 3170132b08..1ccdeb9aa3 100644 --- a/libavformat/img2dec.c +++ b/libavformat/img2dec.c @@ -27,6 +27,7 @@ #include #include "libavutil/avassert.h" #include "libavutil/avstring.h" +#include "libavutil/bprint.h" #include "libavutil/log.h" #include "libavutil/mem.h" #include "libavutil/opt.h" @@ -96,18 +97,23 @@ static int infer_size(int *width_ptr, int *height_ptr, int size) static int find_image_range(int *pfirst_index, int *plast_index, const char *path, int start_index, int start_index_range) { - char buf[1024]; - int range, last_index, range1, first_index; + int range, last_index, range1, first_index, ret; + AVBPrint filename; + av_bprint_init(&filename, 0, AV_BPRINT_SIZE_UNLIMITED); /* find the first image */ for (first_index = start_index; first_index < start_index + start_index_range; first_index++) { - if (av_get_frame_filename(buf, sizeof(buf), path, first_index) < 0) - return -1; - if (avio_check(buf, AVIO_FLAG_READ) > 0) + av_bprint_clear(&filename); + ret = ff_bprint_get_frame_filename(&filename, path, first_index, 0); + if (ret < 0) + goto fail; + if (avio_check(filename.str, AVIO_FLAG_READ) > 0) break; } - if (first_index == start_index + start_index_range) + if (first_index == start_index + start_index_range) { + ret = AVERROR(EINVAL); goto fail; + } /* find the last image */ last_index = first_index; @@ -118,15 +124,18 @@ static int find_image_range(int *pfirst_index, int *plast_index, range1 = 1; else range1 = 2 * range; - if (av_get_frame_filename(buf, sizeof(buf), path, - last_index + range1) < 0) + av_bprint_clear(&filename); + ret = ff_bprint_get_frame_filename(&filename, path, last_index + range1, 0); + if (ret < 0) goto fail; - if (avio_check(buf, AVIO_FLAG_READ) <= 0) + if (avio_check(filename.str, AVIO_FLAG_READ) <= 0) break; range = range1; /* just in case... */ - if (range >= (1 << 30)) + if (range >= (1 << 30)) { + ret = AVERROR(EINVAL); goto fail; + } } /* we are sure than image last_index + range exists */ if (!range) @@ -135,10 +144,10 @@ static int find_image_range(int *pfirst_index, int *plast_index, } *pfirst_index = first_index; *plast_index = last_index; - return 0; - + ret = 0; fail: - return -1; + av_bprint_finalize(&filename, NULL); + return ret; } static int img_read_probe(const AVProbeData *p) -- 2.49.1 >>From f9a7a6cd1d487ffebf798d651ee3a94adeb8d9c5 Mon Sep 17 00:00:00 2001 From: Marton Balint Date: Sun, 17 Aug 2025 23:50:09 +0200 Subject: [PATCH 7/7] avformat/img2dec: support arbitrary path lengths Signed-off-by: Marton Balint --- libavformat/img2.h | 1 - libavformat/img2dec.c | 56 +++++++++++++++++++++++++------------------ 2 files changed, 33 insertions(+), 24 deletions(-) diff --git a/libavformat/img2.h b/libavformat/img2.h index 0781e681c5..6da9e47a97 100644 --- a/libavformat/img2.h +++ b/libavformat/img2.h @@ -46,7 +46,6 @@ typedef struct VideoDemuxData { int img_count; int is_pipe; int split_planes; /**< use independent file for each Y, U, V plane */ - char path[1024]; char *pixel_format; /**< Set by a private option. */ int width, height; /**< Set by a private option. */ AVRational framerate; /**< Set by a private option. */ diff --git a/libavformat/img2dec.c b/libavformat/img2dec.c index 1ccdeb9aa3..789f8b94c9 100644 --- a/libavformat/img2dec.c +++ b/libavformat/img2dec.c @@ -188,7 +188,6 @@ int ff_img_read_header(AVFormatContext *s1) return AVERROR(EINVAL); } - av_strlcpy(s->path, s1->url, sizeof(s->path)); s->img_number = 0; s->img_count = 0; @@ -226,22 +225,22 @@ int ff_img_read_header(AVFormatContext *s1) s->pattern_type = PT_SEQUENCE; } if (s->pattern_type == PT_SEQUENCE) { - if (find_image_range(&first_index, &last_index, s->path, + if (find_image_range(&first_index, &last_index, s1->url, s->start_number, s->start_number_range) < 0) { - if (s1->pb || avio_check(s->path, AVIO_FLAG_READ) > 0) { + if (s1->pb || avio_check(s1->url, AVIO_FLAG_READ) > 0) { // Fallback to normal mode s->pattern_type = PT_NONE; } else { av_log(s1, AV_LOG_ERROR, "Could find no file or sequence with path '%s' and index in the range %d-%d\n", - s->path, s->start_number, s->start_number + s->start_number_range - 1); + s1->url, s->start_number, s->start_number + s->start_number_range - 1); return AVERROR(ENOENT); } } } else if (s->pattern_type == PT_GLOB) { #if HAVE_GLOB int gerr; - gerr = glob(s->path, GLOB_NOCHECK|GLOB_BRACE|GLOB_NOMAGIC, NULL, &s->globstate); + gerr = glob(s1->url, GLOB_NOCHECK|GLOB_BRACE|GLOB_NOMAGIC, NULL, &s->globstate); if (gerr != 0) { return AVERROR(ENOENT); } @@ -279,7 +278,7 @@ int ff_img_read_header(AVFormatContext *s1) st->codecpar->codec_type = AVMEDIA_TYPE_VIDEO; st->codecpar->codec_id = ffifmt(s1->iformat)->raw_codec_id; } else { - const char *str = strrchr(s->path, '.'); + const char *str = strrchr(s1->url, '.'); s->split_planes = str && !av_strcasecmp(str + 1, "y"); st->codecpar->codec_type = AVMEDIA_TYPE_VIDEO; if (s1->pb) { @@ -322,7 +321,7 @@ int ff_img_read_header(AVFormatContext *s1) ffio_rewind_with_probe_data(s1->pb, &probe_buffer, probe_buffer_size); } if (st->codecpar->codec_id == AV_CODEC_ID_NONE) - st->codecpar->codec_id = ff_guess_image2_codec(s->path); + st->codecpar->codec_id = ff_guess_image2_codec(s1->url); if (st->codecpar->codec_id == AV_CODEC_ID_LJPEG) st->codecpar->codec_id = AV_CODEC_ID_MJPEG; if (st->codecpar->codec_id == AV_CODEC_ID_ALIAS_PIX) // we cannot distinguish this from BRENDER_PIX @@ -364,13 +363,13 @@ static int add_filename_as_pkt_side_data(char *filename, AVPacket *pkt) { int ff_img_read_packet(AVFormatContext *s1, AVPacket *pkt) { VideoDemuxData *s = s1->priv_data; - char filename_bytes[1024]; - char *filename = filename_bytes; + AVBPrint filename; int i, res; int size[3] = { 0 }, ret[3] = { 0 }; AVIOContext *f[3] = { NULL }; AVCodecParameters *par = s1->streams[0]->codecpar; + av_bprint_init(&filename, 0, AV_BPRINT_SIZE_UNLIMITED); if (!s->is_pipe) { /* loop over input */ if (s->loop && s->img_number > s->img_last) { @@ -379,36 +378,43 @@ int ff_img_read_packet(AVFormatContext *s1, AVPacket *pkt) if (s->img_number > s->img_last) return AVERROR_EOF; if (s->pattern_type == PT_NONE) { - av_strlcpy(filename_bytes, s->path, sizeof(filename_bytes)); + av_bprintf(&filename, "%s", s1->url); } else if (s->use_glob) { #if HAVE_GLOB - filename = s->globstate.gl_pathv[s->img_number]; + av_bprintf(&filename, "%s", s->globstate.gl_pathv[s->img_number]); #endif } else { - if (av_get_frame_filename(filename_bytes, sizeof(filename_bytes), - s->path, - s->img_number) < 0) - return AVERROR(EIO); + int ret = ff_bprint_get_frame_filename(&filename, s1->url, s->img_number, 0); + if (ret < 0) { + av_bprint_finalize(&filename, NULL); + return ret; + } + } + if (!av_bprint_is_complete(&filename)) { + av_bprint_finalize(&filename, NULL); + return AVERROR(ENOMEM); } for (i = 0; i < 3; i++) { if (s1->pb && - !strcmp(filename_bytes, s->path) && + !strcmp(filename.str, s1->url) && !s->loop && !s->split_planes) { f[i] = s1->pb; - } else if (s1->io_open(s1, &f[i], filename, AVIO_FLAG_READ, NULL) < 0) { + } else if (s1->io_open(s1, &f[i], filename.str, AVIO_FLAG_READ, NULL) < 0) { if (i >= 1) break; av_log(s1, AV_LOG_ERROR, "Could not open file : %s\n", - filename); + filename.str); + av_bprint_finalize(&filename, NULL); return AVERROR(EIO); } size[i] = avio_size(f[i]); if (!s->split_planes) break; - filename[strlen(filename) - 1] = 'U' + i; + filename.str[filename.len - 1] = 'U' + i; } + av_bprint_finalize(&filename, NULL); if (par->codec_id == AV_CODEC_ID_NONE) { AVProbeData pd = { 0 }; @@ -418,13 +424,15 @@ int ff_img_read_packet(AVFormatContext *s1, AVPacket *pkt) int score = 0; ret = avio_read(f[0], header, PROBE_BUF_MIN); - if (ret < 0) + if (ret < 0) { + av_bprint_finalize(&filename, NULL); return ret; + } memset(header + ret, 0, sizeof(header) - ret); avio_skip(f[0], -ret); pd.buf = header; pd.buf_size = ret; - pd.filename = filename; + pd.filename = filename.str; ifmt = ffifmt(av_probe_input_format3(&pd, 1, &score)); if (ifmt && ifmt->read_packet == ff_img_read_packet && ifmt->raw_codec_id) @@ -457,7 +465,7 @@ int ff_img_read_packet(AVFormatContext *s1, AVPacket *pkt) if (s->ts_from_file) { struct stat img_stat; av_assert0(!s->is_pipe); // The ts_from_file option is not supported by piped input demuxers - if (stat(filename, &img_stat)) { + if (stat(filename.str, &img_stat)) { res = AVERROR(EIO); goto fail; } @@ -480,10 +488,11 @@ int ff_img_read_packet(AVFormatContext *s1, AVPacket *pkt) * as packet side_data. */ if (!s->is_pipe && s->export_path_metadata == 1) { - res = add_filename_as_pkt_side_data(filename, pkt); + res = add_filename_as_pkt_side_data(filename.str, pkt); if (res < 0) goto fail; } + av_bprint_finalize(&filename, NULL); pkt->size = 0; for (i = 0; i < 3; i++) { @@ -522,6 +531,7 @@ int ff_img_read_packet(AVFormatContext *s1, AVPacket *pkt) } fail: + av_bprint_finalize(&filename, NULL); if (!s->is_pipe) { for (i = 0; i < 3; i++) { if (f[i] != s1->pb) -- 2.49.1 _______________________________________________ ffmpeg-devel mailing list -- ffmpeg-devel@ffmpeg.org To unsubscribe send an email to ffmpeg-devel-leave@ffmpeg.org