| 1049 | } |
| 1050 | |
| 1051 | static int parse_cookie(HTTPContext *s, const char *p, AVDictionary **cookies) |
| 1052 | { |
| 1053 | AVDictionary *new_params = NULL; |
| 1054 | const AVDictionaryEntry *e, *cookie_entry; |
| 1055 | char *eql, *name; |
| 1056 | |
| 1057 | // ensure the cookie is parsable |
| 1058 | if (parse_set_cookie(p, &new_params)) |
| 1059 | return -1; |
| 1060 | |
| 1061 | // if there is no cookie value there is nothing to parse |
| 1062 | cookie_entry = av_dict_iterate(new_params, NULL); |
| 1063 | if (!cookie_entry || !cookie_entry->value) { |
| 1064 | av_dict_free(&new_params); |
| 1065 | return -1; |
| 1066 | } |
| 1067 | |
| 1068 | // ensure the cookie is not expired or older than an existing value |
| 1069 | if ((e = av_dict_get(new_params, "expires", NULL, 0)) && e->value) { |
| 1070 | struct tm new_tm = {0}; |
| 1071 | if (!parse_http_date(e->value, &new_tm)) { |
| 1072 | AVDictionaryEntry *e2; |
| 1073 | |
| 1074 | // if the cookie has already expired ignore it |
| 1075 | if (av_timegm(&new_tm) < av_gettime() / 1000000) { |
| 1076 | av_dict_free(&new_params); |
| 1077 | return 0; |
| 1078 | } |
| 1079 | |
| 1080 | // only replace an older cookie with the same name |
| 1081 | e2 = av_dict_get(*cookies, cookie_entry->key, NULL, 0); |
| 1082 | if (e2 && e2->value) { |
| 1083 | AVDictionary *old_params = NULL; |
| 1084 | if (!parse_set_cookie(p, &old_params)) { |
| 1085 | e2 = av_dict_get(old_params, "expires", NULL, 0); |
| 1086 | if (e2 && e2->value) { |
| 1087 | struct tm old_tm = {0}; |
| 1088 | if (!parse_http_date(e->value, &old_tm)) { |
| 1089 | if (av_timegm(&new_tm) < av_timegm(&old_tm)) { |
| 1090 | av_dict_free(&new_params); |
| 1091 | av_dict_free(&old_params); |
| 1092 | return -1; |
| 1093 | } |
| 1094 | } |
| 1095 | } |
| 1096 | } |
| 1097 | av_dict_free(&old_params); |
| 1098 | } |
| 1099 | } |
| 1100 | } |
| 1101 | av_dict_free(&new_params); |
| 1102 | |
| 1103 | // duplicate the cookie name (dict will dupe the value) |
| 1104 | if (!(eql = strchr(p, '='))) return AVERROR(EINVAL); |
| 1105 | if (!(name = av_strndup(p, eql - p))) return AVERROR(ENOMEM); |
| 1106 | |
| 1107 | // add the cookie to the dictionary |
| 1108 | av_dict_set(cookies, name, eql, AV_DICT_DONT_STRDUP_KEY); |
no test coverage detected