BUG/MINOR: h1: Don't support LF only at the end of chunks
When the message is chunked, all chunks must ends with a CRLF. However, on
old versions, to support bad client or server implementations, the LF only
was also accepted. Nowadays, it seems useless and can even be considered as
an issue. Just forbid LF only at the end of chunks, it seems reasonnable.
This patch must be backported to 2.9 and probably to all stable versions
because there is no reason to still support LF without CR in this case.
(cherry picked from commit 7b737da8258ebdd84e702a2d65cfd3c423f8e96d)
Signed-off-by: Willy Tarreau <w@1wt.eu>
(cherry picked from commit 787b67ddf1512b0b2c8740c2e4018e86d0797fa6)
Signed-off-by: Willy Tarreau <w@1wt.eu>
(cherry picked from commit 8df94eb6f63e2bdc01b46b18a380d4051e0723b4)
Signed-off-by: Christopher Faulet <cfaulet@haproxy.com>
(cherry picked from commit 01a1ebb257655ed5ae5128f8aa3c89a9997e6259)
Signed-off-by: Christopher Faulet <cfaulet@haproxy.com>
(cherry picked from commit 2271f8e8d125b69fc01f431aa5bab422ac595b97)
[cf: only h1_skip_chunk_crlf() had to be fixed]
Signed-off-by: Christopher Faulet <cfaulet@haproxy.com>
diff --git a/include/haproxy/h1.h b/include/haproxy/h1.h
index ab6a30e..8e51f6a 100644
--- a/include/haproxy/h1.h
+++ b/include/haproxy/h1.h
@@ -193,8 +193,8 @@
}
}
-/* This function may be called only in HTTP_MSG_CHUNK_CRLF. It reads the CRLF or
- * a possible LF alone at the end of a chunk. The caller should adjust msg->next
+/* This function may be called only in HTTP_MSG_CHUNK_CRLF. It reads the CRLF
+ * at the end of a chunk. The caller should adjust msg->next
* in order to include this part into the next forwarding phase. Note that the
* caller must ensure that head+start points to the first byte to parse. It
* returns the number of bytes parsed on success, so the caller can set msg_state
@@ -211,16 +211,17 @@
if (stop <= start)
return 0;
+ if (unlikely(*ptr != '\r')) // negative position to stop
+ return ptr - __b_peek(buf, stop);
+
/* NB: we'll check data availability at the end. It's not a
* problem because whatever we match first will be checked
* against the correct length.
*/
- if (*ptr == '\r') {
- bytes++;
- ptr++;
- if (ptr >= b_wrap(buf))
- ptr = b_orig(buf);
- }
+ bytes++;
+ ptr++;
+ if (ptr >= b_wrap(buf))
+ ptr = b_orig(buf);
if (bytes > stop - start)
return 0;