From 7cbbc4f7e7ffdb874a25e269ac92f7bb161c5b83 Mon Sep 17 00:00:00 2001 From: Stefano Sabatini Date: Thu, 28 Nov 2013 16:51:40 +0100 Subject: ffserver: extend error handling when parsing the configuration file In particular, abort immediately in case of memory error, avoid potential crashes. --- ffserver.c | 57 +++++++++++++++++++++++++++++++++++++++++++++------------ 1 file 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; } -- cgit v1.2.3