/* Provenance: curl/curl Curl_build_unencoding_stack (fixed). * repo: curl/curl * commit: 3a09fbb7f264c67c438d01a30669ce325aa508e2 * parent: 6ecdf5136b52af747e7bda08db9a748256b1cd09 * commit_url: https://github.com/curl/curl/commit/3a09fbb7f264c67c438d01a30669ce325aa508e2 * cve: CVE-2022-32206 * license: curl * function: Curl_build_unencoding_stack * relpath: lib/content_encoding.c * provenance: human * mechanism: other */ CURLcode Curl_build_unencoding_stack(struct Curl_easy *data, const char *enclist, int maybechunked) { struct SingleRequest *k = &data->req; int counter = 0; do { const char *name; size_t namelen; /* Parse a single encoding name. */ while(ISSPACE(*enclist) || *enclist == ',') enclist++; name = enclist; for(namelen = 0; *enclist && *enclist != ','; enclist++) if(!ISSPACE(*enclist)) namelen = enclist - name + 1; /* Special case: chunked encoding is handled at the reader level. */ if(maybechunked && namelen == 7 && strncasecompare(name, "chunked", 7)) { k->chunk = TRUE; /* chunks coming our way. */ Curl_httpchunk_init(data); /* init our chunky engine. */ } else if(namelen) { const struct content_encoding *encoding = find_encoding(name, namelen); struct contenc_writer *writer; if(!k->writer_stack) { k->writer_stack = new_unencoding_writer(data, &client_encoding, NULL); if(!k->writer_stack) return CURLE_OUT_OF_MEMORY; } if(!encoding) encoding = &error_encoding; /* Defer error at stack use. */ if(++counter >= MAX_ENCODE_STACK) { failf(data, "Reject response due to %u content encodings", counter); return CURLE_BAD_CONTENT_ENCODING; } /* Stack the unencoding stage. */ writer = new_unencoding_writer(data, encoding, k->writer_stack); if(!writer) return CURLE_OUT_OF_MEMORY; k->writer_stack = writer; } } while(*enclist); return CURLE_OK; }