Message ID | 20170325014218.1329-2-micahgalizia@gmail.com |
---|---|
State | Superseded |
Headers | show |
On Fri, 24 Mar 2017 21:42:18 -0400 Micah Galizia <micahgalizia@gmail.com> wrote: > Signed-off-by: Micah Galizia <micahgalizia@gmail.com> > --- > libavformat/http.c | 41 +++++++++++++++++++++++++++++++++++++---- > 1 file changed, 37 insertions(+), 4 deletions(-) > > diff --git a/libavformat/http.c b/libavformat/http.c > index 293a8a7..37bdacf 100644 > --- a/libavformat/http.c > +++ b/libavformat/http.c > @@ -29,6 +29,7 @@ > #include "libavutil/avstring.h" > #include "libavutil/opt.h" > #include "libavutil/time.h" > +#include "libavutil/parseutils.h" > > #include "avformat.h" > #include "http.h" > @@ -48,6 +49,7 @@ > #define MAX_REDIRECTS 8 > #define HTTP_SINGLE 1 > #define HTTP_MUTLI 2 > +#define WHITESPACES " \n\t\r" > typedef enum { > LOWER_PROTO, > READ_HEADERS, > @@ -877,7 +879,7 @@ static int get_cookies(HTTPContext *s, char **cookies, const char *path, > > *cookies = NULL; > while ((cookie = av_strtok(set_cookies, "\n", &next))) { > - int domain_offset = 0; > + int domain_offset = 0, expired = 0; > char *param, *next_param, *cdomain = NULL, *cpath = NULL, *cvalue = NULL; > set_cookies = NULL; > > @@ -885,7 +887,11 @@ static int get_cookies(HTTPContext *s, char **cookies, const char *path, > if (parse_cookie(s, cookie, &s->cookie_dict)) > av_log(s, AV_LOG_WARNING, "Unable to parse '%s'\n", cookie); > > - while ((param = av_strtok(cookie, "; ", &next_param))) { > + while ((param = av_strtok(cookie, ";", &next_param))) { > + > + // move past any leading whitespace > + param += strspn(param, WHITESPACES); > + Not quite sure why this change is even needed, but seems ok. > if (cookie) { > // first key-value pair is the actual cookie value > cvalue = av_strdup(param); > @@ -899,6 +905,33 @@ static int get_cookies(HTTPContext *s, char **cookies, const char *path, > int leading_dot = (param[7] == '.'); > av_free(cdomain); > cdomain = av_strdup(¶m[7+leading_dot]); > + } else if (!av_strncasecmp("expires=", param, 8)) { > + int i = 0, j = 0; > + struct tm tm_buf = {0}; > + char *expiry = av_strdup(¶m[8]); Unchecked memory allocation that could fail. > + > + // strip off any punctuation or whitespace > + for (; i < strlen(expiry); i++) { A bit ugly stylistically: the i=0 initialization should be in here, and the strlen should be cached in a variable, instead of recomputing it on every loop. > + if ((expiry[i] >= '0' && expiry[i] <= '9') || > + (expiry[i] >= 'A' && expiry[i] <= 'Z') || > + (expiry[i] >= 'a' && expiry[i] <= 'z')) { > + expiry[j] = expiry[i]; > + j++; > + } > + } > + expiry[j] = '\0'; (To be honest I don't understand why the string is even strduped - you could just make it with a fixed-sized on-stack buffer. Just discard the remainder of the string if the buffer is unexpectedly too small - time strings probably have an upper size bound anyway.) > + > + // move the string beyond the day of week > + i = 0; > + while ((expiry[i] < '0' || expiry[i] > '9') && (i < j)) > + i++; > + > + if (av_small_strptime(&expiry[i], "%d%b%Y%H%M%SGMT", &tm_buf)) { > + if (av_timegm(&tm_buf) < time(NULL)) > + expired = 1; A bit unsure about this time() call. Also nervous about having this in library code. > + } > + > + av_free(expiry); > } else { > // ignore unknown attributes > } > @@ -907,9 +940,9 @@ static int get_cookies(HTTPContext *s, char **cookies, const char *path, > cdomain = av_strdup(domain); > > // ensure all of the necessary values are valid > - if (!cdomain || !cpath || !cvalue) { > + if (expired || !cdomain || !cpath || !cvalue ) { > av_log(s, AV_LOG_WARNING, > - "Invalid cookie found, no value, path or domain specified\n"); > + "Invalid cookie found, expired or no value, path or domain specified\n"); > goto done_cookie; > } >
On 2017-03-25 07:11 AM, wm4 wrote: <snip> >> - while ((param = av_strtok(cookie, "; ", &next_param))) { >> + while ((param = av_strtok(cookie, ";", &next_param))) { >> + >> + // move past any leading whitespace >> + param += strspn(param, WHITESPACES); >> + > Not quite sure why this change is even needed, but seems ok. Its just a little more flexible than expecting a single space and only a space between each delimited field of a cookie. >> if (cookie) { >> // first key-value pair is the actual cookie value >> cvalue = av_strdup(param); >> @@ -899,6 +905,33 @@ static int get_cookies(HTTPContext *s, char **cookies, const char *path, >> int leading_dot = (param[7] == '.'); >> av_free(cdomain); >> cdomain = av_strdup(¶m[7+leading_dot]); >> + } else if (!av_strncasecmp("expires=", param, 8)) { >> + int i = 0, j = 0; >> + struct tm tm_buf = {0}; >> + char *expiry = av_strdup(¶m[8]); > Unchecked memory allocation that could fail. Thanks, resolved using the on-stack buffer described below. >> + >> + // strip off any punctuation or whitespace >> + for (; i < strlen(expiry); i++) { > A bit ugly stylistically: the i=0 initialization should be in here, and > the strlen should be cached in a variable, instead of recomputing it on > every loop. Fixed. >> + if ((expiry[i] >= '0' && expiry[i] <= '9') || >> + (expiry[i] >= 'A' && expiry[i] <= 'Z') || >> + (expiry[i] >= 'a' && expiry[i] <= 'z')) { >> + expiry[j] = expiry[i]; >> + j++; >> + } >> + } >> + expiry[j] = '\0'; > (To be honest I don't understand why the string is even strduped - you > could just make it with a fixed-sized on-stack buffer. Just discard the > remainder of the string if the buffer is unexpectedly too small - time > strings probably have an upper size bound anyway.) Changed. >> + >> + // move the string beyond the day of week >> + i = 0; >> + while ((expiry[i] < '0' || expiry[i] > '9') && (i < j)) >> + i++; >> + >> + if (av_small_strptime(&expiry[i], "%d%b%Y%H%M%SGMT", &tm_buf)) { >> + if (av_timegm(&tm_buf) < time(NULL)) >> + expired = 1; > A bit unsure about this time() call. Also nervous about having this in > library code. I borrowed some code from parseutils to resolve this. Thanks for the prompt review.
diff --git a/libavformat/http.c b/libavformat/http.c index 293a8a7..37bdacf 100644 --- a/libavformat/http.c +++ b/libavformat/http.c @@ -29,6 +29,7 @@ #include "libavutil/avstring.h" #include "libavutil/opt.h" #include "libavutil/time.h" +#include "libavutil/parseutils.h" #include "avformat.h" #include "http.h" @@ -48,6 +49,7 @@ #define MAX_REDIRECTS 8 #define HTTP_SINGLE 1 #define HTTP_MUTLI 2 +#define WHITESPACES " \n\t\r" typedef enum { LOWER_PROTO, READ_HEADERS, @@ -877,7 +879,7 @@ static int get_cookies(HTTPContext *s, char **cookies, const char *path, *cookies = NULL; while ((cookie = av_strtok(set_cookies, "\n", &next))) { - int domain_offset = 0; + int domain_offset = 0, expired = 0; char *param, *next_param, *cdomain = NULL, *cpath = NULL, *cvalue = NULL; set_cookies = NULL; @@ -885,7 +887,11 @@ static int get_cookies(HTTPContext *s, char **cookies, const char *path, if (parse_cookie(s, cookie, &s->cookie_dict)) av_log(s, AV_LOG_WARNING, "Unable to parse '%s'\n", cookie); - while ((param = av_strtok(cookie, "; ", &next_param))) { + while ((param = av_strtok(cookie, ";", &next_param))) { + + // move past any leading whitespace + param += strspn(param, WHITESPACES); + if (cookie) { // first key-value pair is the actual cookie value cvalue = av_strdup(param); @@ -899,6 +905,33 @@ static int get_cookies(HTTPContext *s, char **cookies, const char *path, int leading_dot = (param[7] == '.'); av_free(cdomain); cdomain = av_strdup(¶m[7+leading_dot]); + } else if (!av_strncasecmp("expires=", param, 8)) { + int i = 0, j = 0; + struct tm tm_buf = {0}; + char *expiry = av_strdup(¶m[8]); + + // strip off any punctuation or whitespace + for (; i < strlen(expiry); i++) { + if ((expiry[i] >= '0' && expiry[i] <= '9') || + (expiry[i] >= 'A' && expiry[i] <= 'Z') || + (expiry[i] >= 'a' && expiry[i] <= 'z')) { + expiry[j] = expiry[i]; + j++; + } + } + expiry[j] = '\0'; + + // move the string beyond the day of week + i = 0; + while ((expiry[i] < '0' || expiry[i] > '9') && (i < j)) + i++; + + if (av_small_strptime(&expiry[i], "%d%b%Y%H%M%SGMT", &tm_buf)) { + if (av_timegm(&tm_buf) < time(NULL)) + expired = 1; + } + + av_free(expiry); } else { // ignore unknown attributes } @@ -907,9 +940,9 @@ static int get_cookies(HTTPContext *s, char **cookies, const char *path, cdomain = av_strdup(domain); // ensure all of the necessary values are valid - if (!cdomain || !cpath || !cvalue) { + if (expired || !cdomain || !cpath || !cvalue ) { av_log(s, AV_LOG_WARNING, - "Invalid cookie found, no value, path or domain specified\n"); + "Invalid cookie found, expired or no value, path or domain specified\n"); goto done_cookie; }
Signed-off-by: Micah Galizia <micahgalizia@gmail.com> --- libavformat/http.c | 41 +++++++++++++++++++++++++++++++++++++---- 1 file changed, 37 insertions(+), 4 deletions(-)