altsvc: continue after unknown parameters
No binary (build failed)
—
(log yok)
| @@ -471,6 +471,8 @@ static void altsvc_flush(struct altsvcinfo *asi, | |
| } | |
| } | |
| + | #define ALTSVC_MA 1 |
| + | #define ALTSVC_PERSIST 2 |
| static void altsvc_parse_params(const char **pp, | |
| time_t *pmaxage, | |
| bool *ppersist) | |
| @@ -482,36 +484,44 @@ static void altsvc_parse_params(const char **pp, | |
| for(;;) { | |
| struct Curl_str name; | |
| struct Curl_str val; | |
| - | const char *vp; |
| curl_off_t num; | |
| - | bool quoted; |
| + | int keyword = 0; |
| /* allow some extra whitespaces around name and value */ | |
| - | if(curlx_str_until(pp, &name, 20, '=') || |
| - | curlx_str_single(pp, '=') || |
| - | curlx_str_cspn(pp, &val, ",;")) |
| + | if(curlx_str_until(pp, &name, MAX_ALTSVC_LINE, '=') || |
| + | curlx_str_single(pp, '=')) |
| break; /* skip further parameter parsing */ | |
| curlx_str_trimblanks(&name); | |
| + | curlx_str_passblanks(pp); |
| + | if(**pp == '\"') { |
| + | if(curlx_str_quotedword(pp, &val, MAX_ALTSVC_LINE)) |
| + | break; |
| + | } |
| + | else { |
| + | if(curlx_str_cspn(pp, &val, ",;\r\n")) |
| + | break; |
| + | } |
| curlx_str_trimblanks(&val); | |
| - | /* the value might be quoted */ |
| - | vp = curlx_str(&val); |
| - | quoted = (*vp == '\"'); |
| - | if(quoted) |
| - | vp++; |
| - | /* we process 2 number value parameters: 'ma' and 'persist' */ |
| - | if(curlx_str_number(&vp, &num, TIME_T_MAX)) |
| - | break; /* not a number, skip further parameter parsing */ |
| if(curlx_str_casecompare(&name, "ma")) | |
| - | *pmaxage = (time_t)num; |
| - | else if(curlx_str_casecompare(&name, "persist") && (num == 1)) |
| - | *ppersist = TRUE; |
| + | keyword = ALTSVC_MA; |
| + | else if(curlx_str_casecompare(&name, "persist")) |
| + | keyword = ALTSVC_PERSIST; |
| + | |
| + | if(keyword) { |
| + | const char *vp = curlx_str(&val); |
| + | const char *vend = vp + curlx_strlen(&val); |
| + | if(curlx_str_number(&vp, &num, TIME_T_MAX)) |
| + | break; /* not a number, skip further parameter parsing */ |
| + | if(vp != vend) |
| + | break; /* not entirely a number, skip further parameter parsing */ |
| + | if(keyword == ALTSVC_MA) |
| + | *pmaxage = (time_t)num; |
| + | else if(num == 1) |
| + | *ppersist = TRUE; |
| + | } |
| - | *pp = vp; /* point to the byte ending the value */ |
| - | curlx_str_passblanks(pp); |
| - | if(quoted && curlx_str_single(pp, '\"')) |
| - | break; /* was quoted but not ended in quote, skip */ |
| curlx_str_passblanks(pp); | |
| if(curlx_str_single(pp, ';')) | |
| break; /* no further parameters */ | |
| @@ -34,8 +34,10 @@ static CURLcode test_unit1654(const char *arg) | |
| CURL *curl = NULL; | |
| CURLcode result; | |
| struct altsvcinfo *asi = Curl_altsvc_init(); | |
| + | struct altsvc *dstentry = NULL; |
| struct Curl_peer *origin = NULL; | |
| const struct Curl_scheme *scheme = &Curl_scheme_https; | |
| + | bool same_destination = FALSE; |
| abort_if(!asi, "Curl_altsvc_i"); | |
| result = Curl_altsvc_load(asi, arg); | |
| @@ -160,6 +162,28 @@ static CURLcode test_unit1654(const char *arg) | |
| origin, ALPN_h2); | |
| fail_if(result, "Curl_altsvc_parse(12) failed!"); | |
| + | /* Unknown extension parameters must not hide later known parameters. */ |
| + | if(Curl_peer_create(curl, scheme, "params.example", 443, &origin)) |
| + | goto fail; |
| + | result = Curl_altsvc_parse(curl, asi, |
| + | "h2=\":443\"; long-extension-parameter=token; " |
| + | "ext=token; " |
| + | "quoted=\"a;\\\"b\"; ma=120; persist=1\r\n", |
| + | origin, ALPN_h1); |
| + | fail_if(result, "Curl_altsvc_parse(13) failed!"); |
| + | if(!Curl_altsvc_lookup(asi, origin, ALPN_h1, &dstentry, |
| + | CURLALTSVC_H2, &same_destination)) { |
| + | fail_unless(FALSE, "alt-svc entry not found"); |
| + | goto fail; |
| + | } |
| + | fail_unless(dstentry->expires == 1548369261 + 120, |
| + | "unknown parameters hid ma"); |
| + | fail_unless(dstentry->persist, "unknown parameters hid persist"); |
| + | fail_unless(same_destination, "wrong alt-svc destination"); |
| + | |
| + | result = Curl_altsvc_parse(curl, asi, "clear\r\n", origin, ALPN_h1); |
| + | fail_if(result, "Curl_altsvc_parse(14) failed!"); |
| + | |
| Curl_altsvc_save(curl, asi, outname); | |
| fail: | |