diff mbox series

[FFmpeg-devel,v3,3/5] avformat/{aviobuf, avio_internal}: add max_len argument to ff_read_string_to_bprint_overwrite

Message ID 20210920150048.8790-4-jeebjp@gmail.com
State Accepted
Commit 847fd8de7c13abe41ca59464014f17c56555ef7b
Headers show
Series Support for stream dispositions in MP4
Related show

Checks

Context Check Description
andriy/commit_msg_x86 warning The first line of the commit message must start with a context terminated by a colon and a space, for example "lavu/opt: " or "doc: ".
andriy/make_x86 success Make finished
andriy/make_fate_x86 success Make fate finished

Commit Message

Jan Ekström Sept. 20, 2021, 3 p.m. UTC
From: Jan Ekström <jan.ekstrom@24i.com>

This is especially useful when reading things such as null-terminated
strings from MOV/MP4-likes, where the size of the box is known, but
not the exact size of the string.

Signed-off-by: Jan Ekström <jan.ekstrom@24i.com>
---
 libavformat/avio_internal.h | 13 ++++++++++---
 libavformat/aviobuf.c       | 23 +++++++++++++++--------
 2 files changed, 25 insertions(+), 11 deletions(-)
diff mbox series

Patch

diff --git a/libavformat/avio_internal.h b/libavformat/avio_internal.h
index 3b3ed3b619..e40adc944e 100644
--- a/libavformat/avio_internal.h
+++ b/libavformat/avio_internal.h
@@ -247,14 +247,21 @@  int64_t ff_read_line_to_bprint_overwrite(AVIOContext *s, struct AVBPrint *bp);
 
 /**
  * Read a whole null-terminated string of text from AVIOContext to an AVBPrint
- * buffer overwriting its contents. Stop reading after reaching a \\0 or
- * EOF.
+ * buffer overwriting its contents. Stop reading after reaching the maximum
+ * length, a \\0 or EOF.
  *
  * @param s the read-only AVIOContext
  * @param bp the AVBPrint buffer
+ * @param max_len the maximum length to be read from the AVIOContext.
+ *                Negative (< 0) values signal that there is no known maximum
+ *                length applicable. A maximum length of zero means that the
+ *                AVIOContext is not touched, and the function returns
+ *                with a read length of zero. In all cases the AVBprint
+ *                is cleared.
  * @return the length of the read string not including the terminating null,
  *         negative on error, or if the buffer becomes truncated.
  */
-int64_t ff_read_string_to_bprint_overwrite(AVIOContext *s, AVBPrint *bp);
+int64_t ff_read_string_to_bprint_overwrite(AVIOContext *s, struct AVBPrint *bp,
+                                           int64_t max_len);
 
 #endif /* AVFORMAT_AVIO_INTERNAL_H */
diff --git a/libavformat/aviobuf.c b/libavformat/aviobuf.c
index 3b6f9aed42..b43b24302b 100644
--- a/libavformat/aviobuf.c
+++ b/libavformat/aviobuf.c
@@ -809,13 +809,17 @@  typedef enum FFBPrintReadStringMode {
 } FFBPrintReadStringMode;
 
 static int64_t read_string_to_bprint(AVIOContext *s, AVBPrint *bp,
-                                     FFBPrintReadStringMode mode)
+                                     FFBPrintReadStringMode mode,
+                                     int64_t max_len)
 {
     int len, end;
     int64_t read = 0;
     char tmp[1024];
     char c;
 
+    if (!max_len)
+        return 0;
+
     do {
         len = 0;
         do {
@@ -824,10 +828,11 @@  static int64_t read_string_to_bprint(AVIOContext *s, AVBPrint *bp,
                    c == '\0');
             if (!end)
                 tmp[len++] = c;
-        } while (!end && len < sizeof(tmp));
+        } while (!end && len < sizeof(tmp) &&
+                 ((max_len < 0) || (read + len < max_len)));
         av_bprint_append_data(bp, tmp, len);
         read += len;
-    } while (!end);
+    } while (!end && ((max_len < 0) || (read < max_len)));
 
     if (mode == FFBPrintReadLine &&
         c == '\r' && avio_r8(s) != '\n' && !avio_feof(s))
@@ -843,12 +848,13 @@  static int64_t read_string_to_bprint(AVIOContext *s, AVBPrint *bp,
 }
 
 static int64_t read_string_to_bprint_overwrite(AVIOContext *s, AVBPrint *bp,
-                                               FFBPrintReadStringMode mode)
+                                               FFBPrintReadStringMode mode,
+                                               int64_t max_len)
 {
     int64_t ret;
 
     av_bprint_clear(bp);
-    ret = read_string_to_bprint(s, bp, mode);
+    ret = read_string_to_bprint(s, bp, mode, max_len);
     if (ret < 0)
         return ret;
 
@@ -860,12 +866,13 @@  static int64_t read_string_to_bprint_overwrite(AVIOContext *s, AVBPrint *bp,
 
 int64_t ff_read_line_to_bprint_overwrite(AVIOContext *s, AVBPrint *bp)
 {
-    return read_string_to_bprint_overwrite(s, bp, FFBPrintReadLine);
+    return read_string_to_bprint_overwrite(s, bp, FFBPrintReadLine, -1);
 }
 
-int64_t ff_read_string_to_bprint_overwrite(AVIOContext *s, AVBPrint *bp)
+int64_t ff_read_string_to_bprint_overwrite(AVIOContext *s, AVBPrint *bp,
+                                           int64_t max_len)
 {
-    return read_string_to_bprint_overwrite(s, bp, FFBPrintReadString);
+    return read_string_to_bprint_overwrite(s, bp, FFBPrintReadString, max_len);
 }
 
 int avio_get_str(AVIOContext *s, int maxlen, char *buf, int buflen)