diff options
author | Stefano Sabatini <stefasab@gmail.com> | 2013-11-28 16:51:40 +0100 |
---|---|---|
committer | Stefano Sabatini <stefasab@gmail.com> | 2013-11-28 23:13:45 +0100 |
commit | 7cbbc4f7e7ffdb874a25e269ac92f7bb161c5b83 (patch) | |
tree | ad8c9c7942f58f14876299016864ea6ed7533f0f /ffserver.c | |
parent | 04702a0d3d73836a3df1a5f61112b02f52c8dd8e (diff) | |
download | ffmpeg-7cbbc4f7e7ffdb874a25e269ac92f7bb161c5b83.tar.gz |
ffserver: extend error handling when parsing the configuration file
In particular, abort immediately in case of memory error, avoid potential
crashes.
Diffstat (limited to 'ffserver.c')
-rw-r--r-- | ffserver.c | 57 |
1 files changed, 45 insertions, 12 deletions
diff --git a/ffserver.c b/ffserver.c index 42e1f7d0c7..5c6db9afd7 100644 --- a/ffserver.c +++ b/ffserver.c @@ -4046,11 +4046,13 @@ static int parse_ffconfig(const char *filename) FFStream **last_feed, *feed, *s; AVCodecContext audio_enc, video_enc; enum AVCodecID audio_id, video_id; + int ret = 0; f = fopen(filename, "r"); if (!f) { - perror(filename); - return -1; + ret = AVERROR(errno); + av_log(NULL, AV_LOG_ERROR, "Could not open the configuration file '%s'\n", filename); + return ret; } errors = 0; @@ -4138,6 +4140,10 @@ static int parse_ffconfig(const char *filename) ERROR("Already in a tag\n"); } else { feed = av_mallocz(sizeof(FFStream)); + if (!feed) { + ret = AVERROR(ENOMEM); + goto end; + } get_arg(feed->filename, sizeof(feed->filename), &p); q = strrchr(feed->filename, '>'); if (*q) @@ -4169,19 +4175,31 @@ static int parse_ffconfig(const char *filename) int i; feed->child_argv = av_mallocz(64 * sizeof(char *)); - + if (!feed->child_argv) { + ret = AVERROR(ENOMEM); + goto end; + } for (i = 0; i < 62; i++) { get_arg(arg, sizeof(arg), &p); if (!arg[0]) break; feed->child_argv[i] = av_strdup(arg); + if (!feed->child_argv[i]) { + ret = AVERROR(ENOMEM); + goto end; + } } - feed->child_argv[i] = av_asprintf("http://%s:%d/%s", - (my_http_addr.sin_addr.s_addr == INADDR_ANY) ? "127.0.0.1" : - inet_ntoa(my_http_addr.sin_addr), - ntohs(my_http_addr.sin_port), feed->filename); + feed->child_argv[i] = + av_asprintf("http://%s:%d/%s", + (my_http_addr.sin_addr.s_addr == INADDR_ANY) ? "127.0.0.1" : + inet_ntoa(my_http_addr.sin_addr), ntohs(my_http_addr.sin_port), + feed->filename); + if (!feed->child_argv[i]) { + ret = AVERROR(ENOMEM); + goto end; + } } } else if (!av_strcasecmp(cmd, "ReadOnlyFile")) { if (feed) { @@ -4238,6 +4256,10 @@ static int parse_ffconfig(const char *filename) } else { FFStream *s; stream = av_mallocz(sizeof(FFStream)); + if (!stream) { + ret = AVERROR(ENOMEM); + goto end; + } get_arg(stream->filename, sizeof(stream->filename), &p); q = strrchr(stream->filename, '>'); if (q) @@ -4407,10 +4429,14 @@ static int parse_ffconfig(const char *filename) } else if (!av_strcasecmp(cmd, "VideoSize")) { get_arg(arg, sizeof(arg), &p); if (stream) { - av_parse_video_size(&video_enc.width, &video_enc.height, arg); - if ((video_enc.width % 16) != 0 || - (video_enc.height % 16) != 0) { - ERROR("Image size must be a multiple of 16\n"); + ret = av_parse_video_size(&video_enc.width, &video_enc.height, arg); + if (ret < 0) { + ERROR("Invalid video size '%s'\n", arg); + } else { + if ((video_enc.width % 16) != 0 || + (video_enc.height % 16) != 0) { + ERROR("Image size must be a multiple of 16\n"); + } } } } else if (!av_strcasecmp(cmd, "VideoFrameRate")) { @@ -4593,6 +4619,10 @@ static int parse_ffconfig(const char *filename) ERROR("Already in a tag\n"); } else { redirect = av_mallocz(sizeof(FFStream)); + if (!redirect) { + ret = AVERROR(ENOMEM); + goto end; + } *last_stream = redirect; last_stream = &redirect->next; @@ -4622,9 +4652,12 @@ static int parse_ffconfig(const char *filename) } #undef ERROR +end: fclose(f); + if (ret < 0) + return ret; if (errors) - return -1; + return AVERROR(EINVAL); else return 0; } |