ffserver: extend error handling when parsing the configuration file

In particular, abort immediately in case of memory error, avoid potential
crashes.
This commit is contained in:
Stefano Sabatini 2013-11-28 16:51:40 +01:00
parent 04702a0d3d
commit 7cbbc4f7e7
1 changed files with 45 additions and 12 deletions

View File

@ -4046,11 +4046,13 @@ static int parse_ffconfig(const char *filename)
FFStream **last_feed, *feed, *s; FFStream **last_feed, *feed, *s;
AVCodecContext audio_enc, video_enc; AVCodecContext audio_enc, video_enc;
enum AVCodecID audio_id, video_id; enum AVCodecID audio_id, video_id;
int ret = 0;
f = fopen(filename, "r"); f = fopen(filename, "r");
if (!f) { if (!f) {
perror(filename); ret = AVERROR(errno);
return -1; av_log(NULL, AV_LOG_ERROR, "Could not open the configuration file '%s'\n", filename);
return ret;
} }
errors = 0; errors = 0;
@ -4138,6 +4140,10 @@ static int parse_ffconfig(const char *filename)
ERROR("Already in a tag\n"); ERROR("Already in a tag\n");
} else { } else {
feed = av_mallocz(sizeof(FFStream)); feed = av_mallocz(sizeof(FFStream));
if (!feed) {
ret = AVERROR(ENOMEM);
goto end;
}
get_arg(feed->filename, sizeof(feed->filename), &p); get_arg(feed->filename, sizeof(feed->filename), &p);
q = strrchr(feed->filename, '>'); q = strrchr(feed->filename, '>');
if (*q) if (*q)
@ -4169,19 +4175,31 @@ static int parse_ffconfig(const char *filename)
int i; int i;
feed->child_argv = av_mallocz(64 * sizeof(char *)); feed->child_argv = av_mallocz(64 * sizeof(char *));
if (!feed->child_argv) {
ret = AVERROR(ENOMEM);
goto end;
}
for (i = 0; i < 62; i++) { for (i = 0; i < 62; i++) {
get_arg(arg, sizeof(arg), &p); get_arg(arg, sizeof(arg), &p);
if (!arg[0]) if (!arg[0])
break; break;
feed->child_argv[i] = av_strdup(arg); 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", feed->child_argv[i] =
(my_http_addr.sin_addr.s_addr == INADDR_ANY) ? "127.0.0.1" : av_asprintf("http://%s:%d/%s",
inet_ntoa(my_http_addr.sin_addr), (my_http_addr.sin_addr.s_addr == INADDR_ANY) ? "127.0.0.1" :
ntohs(my_http_addr.sin_port), feed->filename); 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")) { } else if (!av_strcasecmp(cmd, "ReadOnlyFile")) {
if (feed) { if (feed) {
@ -4238,6 +4256,10 @@ static int parse_ffconfig(const char *filename)
} else { } else {
FFStream *s; FFStream *s;
stream = av_mallocz(sizeof(FFStream)); stream = av_mallocz(sizeof(FFStream));
if (!stream) {
ret = AVERROR(ENOMEM);
goto end;
}
get_arg(stream->filename, sizeof(stream->filename), &p); get_arg(stream->filename, sizeof(stream->filename), &p);
q = strrchr(stream->filename, '>'); q = strrchr(stream->filename, '>');
if (q) if (q)
@ -4407,10 +4429,14 @@ static int parse_ffconfig(const char *filename)
} else if (!av_strcasecmp(cmd, "VideoSize")) { } else if (!av_strcasecmp(cmd, "VideoSize")) {
get_arg(arg, sizeof(arg), &p); get_arg(arg, sizeof(arg), &p);
if (stream) { if (stream) {
av_parse_video_size(&video_enc.width, &video_enc.height, arg); ret = av_parse_video_size(&video_enc.width, &video_enc.height, arg);
if ((video_enc.width % 16) != 0 || if (ret < 0) {
(video_enc.height % 16) != 0) { ERROR("Invalid video size '%s'\n", arg);
ERROR("Image size must be a multiple of 16\n"); } 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")) { } else if (!av_strcasecmp(cmd, "VideoFrameRate")) {
@ -4593,6 +4619,10 @@ static int parse_ffconfig(const char *filename)
ERROR("Already in a tag\n"); ERROR("Already in a tag\n");
} else { } else {
redirect = av_mallocz(sizeof(FFStream)); redirect = av_mallocz(sizeof(FFStream));
if (!redirect) {
ret = AVERROR(ENOMEM);
goto end;
}
*last_stream = redirect; *last_stream = redirect;
last_stream = &redirect->next; last_stream = &redirect->next;
@ -4622,9 +4652,12 @@ static int parse_ffconfig(const char *filename)
} }
#undef ERROR #undef ERROR
end:
fclose(f); fclose(f);
if (ret < 0)
return ret;
if (errors) if (errors)
return -1; return AVERROR(EINVAL);
else else
return 0; return 0;
} }