Version: (using KDE Devel) Installed from: Compiled sources When you submit TEXTAREA type data to a form whose "enctype" attribute is specified as "multipart/form-data", the \r portion of the linefeeds is missing. Under textareas without this encoding type \r is added with \n, which is correct. Mozilla also does this the same, adding \r to each \n This bug has the effect that when you are using software that is expecting DOS style linefeeds, it can break.
and if you work with software that is expecting UNIX style linefeeds, it breaks your way? Is there some standard that talks about the line feeds?
Well, put it this way. Under normal usage (no ENCTYPE attribute specified), KHTML already adds \r to each \n in multiline form fields. So, even if compatibility with Windows applications/sites is not a priority, at the very least it is inconsistent behaviour within KHTML itself. Also, Mozilla always adds \r. I have no access to Opera so I could not check. I don't know if it is an official standard, but it seems to be what everyone seems to be expecting when it comes to multiline textarea submissions.
Another point - the fact that Mozilla always sends both indicates that it in fact would not break other software if we added \r... at least not anything I have ever used in Mozilla .that had textareas with linefeeds. Perhaps Apache/Whoever automatically strips out the \r's when it is sending off the HTTP GET/POST results?
http://www.w3.org/TR/REC-html40/interact/forms.html says: "As with all MIME transmissions, "CR LF" (i.e., `%0D%0A') is used to separate lines of data." Will fix.
CVS commit by waba: Use CRLF in multipart form submissions. (BR83098) CCMAIL: 83098-done@bugs.kde.org M +36 -3 html_formimpl.cpp 1.369 --- kdelibs/khtml/html/html_formimpl.cpp #1.368:1.369 @@ -110,4 +110,36 @@ long HTMLFormElementImpl::length() const } +static QCString expandLF(const QCString& s) +{ + // LF -> CRLF + unsigned crs = s.contains( '\n' ); + if (crs == 0) + return s; + unsigned len = s.length(); + + QCString r(len + s.contains( '\n') *2 + 1); + unsigned pos2 = 0; + for(unsigned pos = 0; pos < len; pos++) + { + char c = s[pos]; + switch(c) + { + case '\n': + r[pos2++] = '\r'; + r[pos2++] = '\n'; + break; + + case '\r': + break; + + default: + r[pos2++]= c; + break; + } + } + r.truncate(pos2); + return r; +} + static QCString encodeCString(const QCString& e) { @@ -286,7 +318,8 @@ QByteArray HTMLFormElementImpl::formData // append body unsigned int old_size = form_data.size(); - form_data.resize( old_size + hstr.length() + (*it).size() + 1); + QCString body = expandLF(*it); + form_data.resize( old_size + hstr.length() + body.size() + 1); memcpy(form_data.data() + old_size, hstr.data(), hstr.length()); - memcpy(form_data.data() + old_size + hstr.length(), *it, (*it).size()); + memcpy(form_data.data() + old_size + hstr.length(), body.data(), body.size()); form_data[form_data.size()-2] = '\r'; form_data[form_data.size()-1] = '\n';
Hi, I was annoyed by my *.png uploads always breaking when using Konqueror so I dived into the code and found the problem. It's the fix to #83098 that replaces '\n' with '\r\n' and '\r' with '' even in binary files. I suggest the attached patch that uses expandLF for all data except file uploads. OK to commit? PS: I'm not subscribed to kfm-devel, please CC me. Created an attachment (id=6715) khtml-upload.patch
CVS commit by coolo: reverting Waldo's commit (for #83098) for beta2. I've got another fix reviewed by Dirk and Waldo, but that will need some more testing CCMAIL: 84179-done@bugs.kde.org CCMAIL: 83098@bugs.kde.org M +3 -36 html_formimpl.cpp 1.377 --- kdelibs/khtml/html/html_formimpl.cpp #1.376:1.377 @@ -110,36 +110,4 @@ long HTMLFormElementImpl::length() const } -static QCString expandLF(const QCString& s) -{ - // LF -> CRLF - unsigned crs = s.contains( '\n' ); - if (crs == 0) - return s; - unsigned len = s.length(); - - QCString r(len + s.contains( '\n') *2 + 1); - unsigned pos2 = 0; - for(unsigned pos = 0; pos < len; pos++) - { - char c = s[pos]; - switch(c) - { - case '\n': - r[pos2++] = '\r'; - r[pos2++] = '\n'; - break; - - case '\r': - break; - - default: - r[pos2++]= c; - break; - } - } - r.truncate(pos2); - return r; -} - static QCString encodeCString(const QCString& e) { @@ -318,8 +286,7 @@ QByteArray HTMLFormElementImpl::formData // append body unsigned int old_size = form_data.size(); - QCString body = expandLF(*it); - form_data.resize( old_size + hstr.length() + body.size() + 1); + form_data.resize( old_size + hstr.length() + (*it).size() + 1); memcpy(form_data.data() + old_size, hstr.data(), hstr.length()); - memcpy(form_data.data() + old_size + hstr.length(), body.data(), body.size()); + memcpy(form_data.data() + old_size + hstr.length(), *it, (*it).size()); form_data[form_data.size()-2] = '\r'; form_data[form_data.size()-1] = '\n';