diff mbox series

[FFmpeg-devel,v3,1/2] avformat/utils: added av_get_frame_filename3() (changed parameter int -> int64_t)

Message ID 20240923101931.790-1-shoutplenty@gmail.com
State New
Headers show
Series [FFmpeg-devel,v3,1/2] avformat/utils: added av_get_frame_filename3() (changed parameter int -> int64_t) | expand

Checks

Context Check Description
yinshiyou/make_loongarch64 success Make finished
yinshiyou/make_fate_loongarch64 success Make fate finished
andriy/make_x86 success Make finished
andriy/make_fate_x86 success Make fate finished

Commit Message

Filip Mašić Sept. 23, 2024, 10:18 a.m. UTC
Resolves an integer overflow with the frame_pts option (issue 11194).

Signed-off-by: Filip Mašić <shoutplenty@gmail.com>
---
 doc/APIchanges         |  3 +++
 libavformat/avformat.h |  7 +++++--
 libavformat/img2enc.c  |  6 ++----
 libavformat/utils.c    | 12 +++++++++---
 libavformat/version.h  |  2 +-
 5 files changed, 20 insertions(+), 10 deletions(-)

Comments

Marton Balint Sept. 25, 2024, 8:42 a.m. UTC | #1
On Mon, 23 Sep 2024, Filip Mašić wrote:

> Resolves an integer overflow with the frame_pts option (issue 11194).
>
> Signed-off-by: Filip Mašić <shoutplenty@gmail.com>
> ---
> doc/APIchanges         |  3 +++
> libavformat/avformat.h |  7 +++++--
> libavformat/img2enc.c  |  6 ++----
> libavformat/utils.c    | 12 +++++++++---
> libavformat/version.h  |  2 +-
> 5 files changed, 20 insertions(+), 10 deletions(-)
>
> diff --git a/doc/APIchanges b/doc/APIchanges
> index 81537fea09..9f091f5ec5 100644
> --- a/doc/APIchanges
> +++ b/doc/APIchanges
> @@ -2,6 +2,9 @@ The last version increases of all libraries were on 2024-03-07
> 
> API changes, most recent first:
> 
> +2024-09-xx - xxxxxxxxxx - lavf 61.7.100 - avformat.h
> +  Add av_get_frame_filename3()
> +
> 2024-09-18 - xxxxxxxxxx - lavc 61.17.100 - packet.h
>   Add AV_PKT_DATA_LCEVC.
> 
> diff --git a/libavformat/avformat.h b/libavformat/avformat.h
> index 56c1c80289..1bc0e716dc 100644
> --- a/libavformat/avformat.h
> +++ b/libavformat/avformat.h
> @@ -2932,11 +2932,14 @@ void av_dump_format(AVFormatContext *ic,
>  *
>  * @param buf destination buffer
>  * @param buf_size destination buffer size
> - * @param path numbered sequence string
> - * @param number frame number
> + * @param path path with substitution template
> + * @param number the number to substitute
>  * @param flags AV_FRAME_FILENAME_FLAGS_*
>  * @return 0 if OK, -1 on format error
>  */
> +int av_get_frame_filename3(char *buf, int buf_size,
> +                          const char *path, int64_t number, int flags);
> +

In general AVBPrint based API for functions like this is preferred to 
discuourage users from limiting the filenames to a fixed size (which 
usually becomes a limitation sooner or later).

E.g: av_get_frame_filename_bprint()

Regards,
Marton

> int av_get_frame_filename2(char *buf, int buf_size,
>                           const char *path, int number, int flags);
> 
> diff --git a/libavformat/img2enc.c b/libavformat/img2enc.c
> index 526a11e5ee..460e6a38bd 100644
> --- a/libavformat/img2enc.c
> +++ b/libavformat/img2enc.c
> @@ -160,13 +160,11 @@ static int write_packet(AVFormatContext *s, AVPacket *pkt)
>             return AVERROR(EINVAL);
>         }
>     } else if (img->frame_pts) {
> -        if (av_get_frame_filename2(filename, sizeof(filename), s->url, pkt->pts, AV_FRAME_FILENAME_FLAGS_MULTIPLE) < 0) {
> +        if (av_get_frame_filename3(filename, sizeof(filename), s->url, pkt->pts, AV_FRAME_FILENAME_FLAGS_MULTIPLE) < 0) {
>             av_log(s, AV_LOG_ERROR, "Cannot write filename by pts of the frames.");
>             return AVERROR(EINVAL);
>         }
> -    } else if (av_get_frame_filename2(filename, sizeof(filename), s->url,
> -                                      img->img_number,
> -                                      AV_FRAME_FILENAME_FLAGS_MULTIPLE) < 0) {
> +    } else if (av_get_frame_filename3(filename, sizeof(filename), s->url, img->img_number, AV_FRAME_FILENAME_FLAGS_MULTIPLE) < 0) {
>         if (img->img_number == img->start_img_number) {
>             av_log(s, AV_LOG_WARNING, "The specified filename '%s' does not contain an image sequence pattern or a pattern is invalid.\n", s->url);
>             av_log(s, AV_LOG_WARNING,
> diff --git a/libavformat/utils.c b/libavformat/utils.c
> index e9ded627ad..0a7ed1a013 100644
> --- a/libavformat/utils.c
> +++ b/libavformat/utils.c
> @@ -19,6 +19,7 @@
>  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
>  */
> 
> +#include <inttypes.h>
> #include <stdint.h>
> 
> #include "config.h"
> @@ -280,7 +281,7 @@ uint64_t ff_parse_ntp_time(uint64_t ntp_ts)
>     return (sec * 1000000) + usec;
> }
> 
> -int av_get_frame_filename2(char *buf, int buf_size, const char *path, int number, int flags)
> +int av_get_frame_filename3(char *buf, int buf_size, const char *path, int64_t number, int flags)
> {
>     const char *p;
>     char *q, buf1[20], c;
> @@ -313,7 +314,7 @@ int av_get_frame_filename2(char *buf, int buf_size, const char *path, int number
>                 percentd_found = 1;
>                 if (number < 0)
>                     nd += 1;
> -                snprintf(buf1, sizeof(buf1), "%0*d", nd, number);
> +                snprintf(buf1, sizeof(buf1), "%0*"PRId64, nd, number);
>                 len = strlen(buf1);
>                 if ((q - buf + len) > buf_size - 1)
>                     goto fail;
> @@ -338,9 +339,14 @@ fail:
>     return -1;
> }
> 
> +int av_get_frame_filename2(char *buf, int buf_size, const char *path, int number, int flags)
> +{
> +    return av_get_frame_filename3(buf, buf_size, path, number, flags);
> +}
> +
> int av_get_frame_filename(char *buf, int buf_size, const char *path, int number)
> {
> -    return av_get_frame_filename2(buf, buf_size, path, number, 0);
> +    return av_get_frame_filename3(buf, buf_size, path, number, 0);
> }
> 
> void av_url_split(char *proto, int proto_size,
> diff --git a/libavformat/version.h b/libavformat/version.h
> index 4bde82abb4..70c554c19c 100644
> --- a/libavformat/version.h
> +++ b/libavformat/version.h
> @@ -31,7 +31,7 @@
> 
> #include "version_major.h"
> 
> -#define LIBAVFORMAT_VERSION_MINOR   6
> +#define LIBAVFORMAT_VERSION_MINOR   7
> #define LIBAVFORMAT_VERSION_MICRO 100
> 
> #define LIBAVFORMAT_VERSION_INT AV_VERSION_INT(LIBAVFORMAT_VERSION_MAJOR, \
> -- 
> 2.46.0.windows.1
>
> _______________________________________________
> ffmpeg-devel mailing list
> ffmpeg-devel@ffmpeg.org
> https://ffmpeg.org/mailman/listinfo/ffmpeg-devel
>
> To unsubscribe, visit link above, or email
> ffmpeg-devel-request@ffmpeg.org with subject "unsubscribe".
Filip Mašić Sept. 25, 2024, 9:26 a.m. UTC | #2
On Wed, 25 Sept 2024 at 09:59, Marton Balint <cus@passwd.hu> wrote:

> In general AVBPrint based API for functions like this is preferred to
> discuourage users from limiting the filenames to a fixed size (which
> usually becomes a limitation sooner or later).
>
> E.g: av_get_frame_filename_bprint()
>
> Regards,
> Marton
>

Currently, this patch to reimplement the function internally is preferred:
https://ffmpeg.org/pipermail/ffmpeg-devel/2024-September/333854.html
https://ffmpeg.org/pipermail/ffmpeg-devel/2024-September/333857.html

That's because it's been suggested by a maintainer and doesn't change the
API/ABI so we can pray it will be merged into the upcoming release and the
bug it was written for finally fixed.

Regarding the API, I don't know what purpose the function serves externally
but in my patch, I did attempt to deprecate all the previous API functions,
so you're welcome to extend it from there and make the replacement
interface use AVBPrint (idk much about that). I'm only interested in the
bugfix I mentioned.

Thanks for your interest in this patch :)
diff mbox series

Patch

diff --git a/doc/APIchanges b/doc/APIchanges
index 81537fea09..9f091f5ec5 100644
--- a/doc/APIchanges
+++ b/doc/APIchanges
@@ -2,6 +2,9 @@  The last version increases of all libraries were on 2024-03-07
 
 API changes, most recent first:
 
+2024-09-xx - xxxxxxxxxx - lavf 61.7.100 - avformat.h
+  Add av_get_frame_filename3()
+
 2024-09-18 - xxxxxxxxxx - lavc 61.17.100 - packet.h
   Add AV_PKT_DATA_LCEVC.
 
diff --git a/libavformat/avformat.h b/libavformat/avformat.h
index 56c1c80289..1bc0e716dc 100644
--- a/libavformat/avformat.h
+++ b/libavformat/avformat.h
@@ -2932,11 +2932,14 @@  void av_dump_format(AVFormatContext *ic,
  *
  * @param buf destination buffer
  * @param buf_size destination buffer size
- * @param path numbered sequence string
- * @param number frame number
+ * @param path path with substitution template
+ * @param number the number to substitute
  * @param flags AV_FRAME_FILENAME_FLAGS_*
  * @return 0 if OK, -1 on format error
  */
+int av_get_frame_filename3(char *buf, int buf_size,
+                          const char *path, int64_t number, int flags);
+
 int av_get_frame_filename2(char *buf, int buf_size,
                           const char *path, int number, int flags);
 
diff --git a/libavformat/img2enc.c b/libavformat/img2enc.c
index 526a11e5ee..460e6a38bd 100644
--- a/libavformat/img2enc.c
+++ b/libavformat/img2enc.c
@@ -160,13 +160,11 @@  static int write_packet(AVFormatContext *s, AVPacket *pkt)
             return AVERROR(EINVAL);
         }
     } else if (img->frame_pts) {
-        if (av_get_frame_filename2(filename, sizeof(filename), s->url, pkt->pts, AV_FRAME_FILENAME_FLAGS_MULTIPLE) < 0) {
+        if (av_get_frame_filename3(filename, sizeof(filename), s->url, pkt->pts, AV_FRAME_FILENAME_FLAGS_MULTIPLE) < 0) {
             av_log(s, AV_LOG_ERROR, "Cannot write filename by pts of the frames.");
             return AVERROR(EINVAL);
         }
-    } else if (av_get_frame_filename2(filename, sizeof(filename), s->url,
-                                      img->img_number,
-                                      AV_FRAME_FILENAME_FLAGS_MULTIPLE) < 0) {
+    } else if (av_get_frame_filename3(filename, sizeof(filename), s->url, img->img_number, AV_FRAME_FILENAME_FLAGS_MULTIPLE) < 0) {
         if (img->img_number == img->start_img_number) {
             av_log(s, AV_LOG_WARNING, "The specified filename '%s' does not contain an image sequence pattern or a pattern is invalid.\n", s->url);
             av_log(s, AV_LOG_WARNING,
diff --git a/libavformat/utils.c b/libavformat/utils.c
index e9ded627ad..0a7ed1a013 100644
--- a/libavformat/utils.c
+++ b/libavformat/utils.c
@@ -19,6 +19,7 @@ 
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
+#include <inttypes.h>
 #include <stdint.h>
 
 #include "config.h"
@@ -280,7 +281,7 @@  uint64_t ff_parse_ntp_time(uint64_t ntp_ts)
     return (sec * 1000000) + usec;
 }
 
-int av_get_frame_filename2(char *buf, int buf_size, const char *path, int number, int flags)
+int av_get_frame_filename3(char *buf, int buf_size, const char *path, int64_t number, int flags)
 {
     const char *p;
     char *q, buf1[20], c;
@@ -313,7 +314,7 @@  int av_get_frame_filename2(char *buf, int buf_size, const char *path, int number
                 percentd_found = 1;
                 if (number < 0)
                     nd += 1;
-                snprintf(buf1, sizeof(buf1), "%0*d", nd, number);
+                snprintf(buf1, sizeof(buf1), "%0*"PRId64, nd, number);
                 len = strlen(buf1);
                 if ((q - buf + len) > buf_size - 1)
                     goto fail;
@@ -338,9 +339,14 @@  fail:
     return -1;
 }
 
+int av_get_frame_filename2(char *buf, int buf_size, const char *path, int number, int flags)
+{
+    return av_get_frame_filename3(buf, buf_size, path, number, flags);
+}
+
 int av_get_frame_filename(char *buf, int buf_size, const char *path, int number)
 {
-    return av_get_frame_filename2(buf, buf_size, path, number, 0);
+    return av_get_frame_filename3(buf, buf_size, path, number, 0);
 }
 
 void av_url_split(char *proto, int proto_size,
diff --git a/libavformat/version.h b/libavformat/version.h
index 4bde82abb4..70c554c19c 100644
--- a/libavformat/version.h
+++ b/libavformat/version.h
@@ -31,7 +31,7 @@ 
 
 #include "version_major.h"
 
-#define LIBAVFORMAT_VERSION_MINOR   6
+#define LIBAVFORMAT_VERSION_MINOR   7
 #define LIBAVFORMAT_VERSION_MICRO 100
 
 #define LIBAVFORMAT_VERSION_INT AV_VERSION_INT(LIBAVFORMAT_VERSION_MAJOR, \