[PATCH] Correctly format <form enctype=text/plain> as key=value\r\n
наб <[email protected]> Thu, 25 Sep 2025 16:53:48 +0200
| Newsgroups | gmane.comp.web.lynx.devel |
|---|---|
| Message-ID | <jhkxx2vkr6murtvzysvb2loqj5pie4zea4gs4mwa5lnprztrox@tarta.nabijaczleweli.xyz> |
<https://html.spec.whatwg.org/multipage/form-control-infrastructure.html#submit-body>:
text/plain
Let pairs be the result of converting to a list of name-value pairs with entry list.
Let body be the result of running the text/plain encoding algorithm with pairs.
Set body to the result of encoding body using encoding.
Let mimeType be `text/plain`.
<https://html.spec.whatwg.org/multipage/form-control-infrastructure.html#text/plain-encoding-algorithm>:
4.10.22.9 Plain text form data
The text/plain encoding algorithm,
given a list of name-value pairs pairs, is as follows:
Let result be the empty string.
For each pair in pairs:
Append pair's name to result.
Append a single U+003D EQUALS SIGN character (=) to result.
Append pair's value to result.
Append a U+000D CARRIAGE RETURN (CR)
U+000A LINE FEED (LF) character pair to result.
Return result.
Payloads using the text/plain format are intended to be
human readable. They are not reliably interpretable by
computer, as the format is ambiguous (for example, there
is no way to distinguish a literal newline in a value from
the newline at the end of the value).
Currently, lynx encodes the form data like
vendor=
http
type=
tar
the correct result (and what we see with this patch) is
vendor=http\r
type=tar\r
These all convert trivially, but F_TEXTAREA_TYPE is delimited varyingly,
in that I think you can get
textarea=line1
line2\r
continuation1
continuation2\r
? but this is not expected to be reproducible per WHATWG,
and the ambiguity was already the case.
Fixes https://bugs.debian.org/1116319
---
src/GridText.c | 44 ++++++++++++++++++--------------------------
1 file changed, 18 insertions(+), 26 deletions(-)
diff --git a/src/GridText.c b/src/GridText.c
index 419f6ee..1a4c6f8 100644
--- a/src/GridText.c
+++ b/src/GridText.c
@@ -11171,8 +11171,7 @@ int HText_SubmitForm(FormInfo * submit_item, DocInfo *doc,
if (submit_item->submit_enctype &&
!strncasecomp(submit_item->submit_enctype, STR_PLAINTEXT, 10)) {
/*
- * Do not hex escape, and use physical newlines
- * to separate name=value pairs. -FM
+ * Do not hex escape, dump key=value\r\n directly.
*/
PlainText = TRUE;
} else if (submit_item->submit_enctype &&
@@ -11776,7 +11775,7 @@ int HText_SubmitForm(FormInfo * submit_item, DocInfo *doc,
first_one = FALSE;
} else {
if (PlainText) {
- BStrCat0(my_query, "\n");
+ /* no additional delimiter beside the \r\n */
} else if (SemiColon) {
BStrCat0(my_query, ";");
} else if (Boundary) {
@@ -11810,12 +11809,11 @@ int HText_SubmitForm(FormInfo * submit_item, DocInfo *doc,
my_data[anchor_count].quote);
HTBprintf(&my_query,
- "%s%s%s%s%s",
+ "%s%s%s%s",
escaped1,
(Boundary ? "" : "="),
- (PlainText ? "\n" : ""),
escaped2,
- ((PlainText && *escaped2) ? "\n" : ""));
+ (PlainText ? "\r\n" : ""));
break;
case F_CHECKBOX_TYPE:
case F_RADIO_TYPE:
@@ -11827,12 +11825,11 @@ int HText_SubmitForm(FormInfo * submit_item, DocInfo *doc,
my_data[anchor_count].quote);
HTBprintf(&my_query,
- "%s%s%s%s%s",
+ "%s%s%s%s",
escaped1,
(Boundary ? "" : "="),
- (PlainText ? "\n" : ""),
escaped2,
- ((PlainText && *escaped2) ? "\n" : ""));
+ (PlainText ? "\r\n" : ""));
break;
case F_SUBMIT_TYPE:
case F_TEXT_SUBMIT_TYPE:
@@ -11873,11 +11870,11 @@ int HText_SubmitForm(FormInfo * submit_item, DocInfo *doc,
"%s.x=0%s%s.y=0%s",
escaped1,
(PlainText ?
- "\n" : (SemiColon ?
+ "\r\n" : (SemiColon ?
";" : "&")),
escaped1,
((PlainText && *escaped1) ?
- "\n" : ""));
+ "\r\n" : ""));
}
} else {
/*
@@ -11885,12 +11882,11 @@ int HText_SubmitForm(FormInfo * submit_item, DocInfo *doc,
* pair. = FM
*/
HTBprintf(&my_query,
- "%s%s%s%s%s",
+ "%s%s%s%s",
escaped1,
(Boundary ? "" : "="),
- (PlainText ? "\n" : ""),
escaped2,
- ((PlainText && *escaped2) ? "\n" : ""));
+ (PlainText ? "\r\n" : ""));
}
break;
case F_RESET_TYPE:
@@ -11917,18 +11913,15 @@ int HText_SubmitForm(FormInfo * submit_item, DocInfo *doc,
MultipartContentType);
HTBprintf(&my_query,
- "%s%s%s%s%s",
+ "%s%s%s%s",
escaped1,
(Boundary ? "" : "="),
- (PlainText ? "\n" : ""),
escaped2,
- ((PlainText && *escaped2) ? "\n" : ""));
+ (PlainText ? "\r\n" : ""));
} else {
- const char *marker = (PlainText
- ? "\n"
- : (Boundary
- ? "\r\n"
- : "%0d%0a"));
+ const char *marker = ((PlainText || Boundary)
+ ? "\r\n"
+ : "%0d%0a");
/*
* This is a continuation of a previous textarea.
@@ -11979,10 +11972,9 @@ int HText_SubmitForm(FormInfo * submit_item, DocInfo *doc,
}
HTBprintf(&my_query,
- "%s%s%s",
+ "%s%s",
escaped1,
- (Boundary ? "" : "="),
- (PlainText ? "\n" : ""));
+ (Boundary ? "" : "="));
/*
* If we have anything more than the trailing null we added,
* append the file-data to the query.
@@ -11992,7 +11984,7 @@ int HText_SubmitForm(FormInfo * submit_item, DocInfo *doc,
BStrData(my_data[anchor_count].data),
BStrLen(my_data[anchor_count].data) - 1);
if (PlainText)
- HTBprintf(&my_query, "\n");
+ HTBprintf(&my_query, "\r\n");
}
break;
#endif /* USE_FILE_UPLOAD */
--
2.39.5
signature.asc
(application/pgp-signature, 833 B)
-----BEGIN PGP SIGNATURE----- iQIzBAABCgAdFiEEfWlHToQCjFzAxEFjvP0LAY0mWPEFAmjVV3sACgkQvP0LAY0m WPHTNg//TyxaJt8wkruETHT+o6F+J17bSf2+pQ96f7fTlxKJLQybCPk1ZHh1+jQA 9SWWjn55zfE8atqtnaUbd3wKYpH6dLhwa5lPLx2oNzKrC3a+lvCFbhvs49Ise7KH pHF4tt2WLvwDQbR6JhFCmXFnR9gZOpvzSGG3DOoKtERYjuicL84GS1ZghSSkP4+6 aA8Mvf80RNh6j/0gd1QXZs+EXCIkfWUR2jMkPLI6Z+G2jgZ2olFRlh9oIVUGuw+i XEczFj2svlCtZdmcLgKcRsuWrnuCnhz6NERFOEuukkCC3F1MsHFQIG35/iGlGdTi oEc97psBJ9D+ar8BGqrk9GT6jOSrlrmK/dBfNZAKrsB//pjfnsvzKAuN3rhweznY N+XqxPk1rIKXihm+dajLM28q45dyvZ7jGpzULlsQDAYvrTMQlZhTA4pUd2Tduknl F0kOlPkLBQ+3N9yYIrGuipVCXyddLDpfxZTeiHARlKF0IPG/QEyt9u6uw3ZNO66S LoICCBY4hEaXv+wBA/9ZQ4JguRX/F1d55r8lcLaQaZVCvzOsxbcV3hHGs79XKvWp Yw2wEAN1nyI2cjbSY11vFFovijlMZBuaXUT+F2k/atHye8AvICRM6F0XshfH97Dx vL9x0u8pXuZ0dtN/8FfIMfyiFG6YZIDvJ+qx63c90/LigxjLI8Y= =SoN2 -----END PGP SIGNATURE-----