mirror of
https://github.com/yhirose/cpp-httplib.git
synced 2026-08-12 05:11:24 +00:00
FormFields and FormFiles were std::multimaps, which sort by field name. RFC 7578 5.2 says a form processor "SHOULD send back results in order" and that "Intermediaries MUST NOT reorder the results", so a handler walking req.form.fields saw the parts alphabetised rather than as they were sent, and a body received for forwarding could not be reproduced. Point both at the insertion-ordered container #2523 generalized, with std::equal_to since field names are case-sensitive. Entries sharing a name already kept their relative order under std::multimap; what is recovered here is the order across different names. Server::read_content() keeps a FormFields::iterator alive across the content callbacks that fill the part it points at, which is the one thing this container could have broken: it is vector-backed, so a later emplace can reallocate and leave an older iterator dangling. The code is safe because the iterator is reassigned by the same emplace that could reallocate, and is only read while the flag set alongside it says so. ContentSurvivesContainerGrowth pins that down with 64 parts, enough to grow the vector through seven reallocations; reverting the reassignment makes it abort under ASan rather than fail quietly. Growth also never copies a part's payload: the parser inserts the entry with an empty content and appends the body bytes afterwards, and both mapped types are nothrow-move-constructible, so a reallocation steals the string buffers rather than deep-copying them.