BUG/MINOR: hlua: _hlua_http_msg_delete incorrect behavior when offset is used
Calling the function with an offset when "offset + len" was superior or equal
to the targeted blk length caused 'v' value to be improperly set.
And because 'v' is directly provided to htx_replace_blk_value(), blk consistency was compromised.
(It seems that blk was overrunning in htx_replace_blk_value() due to
this and header data was overwritten in this case).
This patch adds the missing checks to make the function behave as
expected when offset is set and offset+len is greater or equals to the targeted blk length.
Some comments were added to the function as well.
It may be backported to 2.6 and 2.5
diff --git a/src/hlua.c b/src/hlua.c
index 5afe7db..2f6ed27 100644
--- a/src/hlua.c
+++ b/src/hlua.c
@@ -6485,6 +6485,11 @@
/* Be sure <len> is always the amount of DATA to remove */
if (htx->data == offset+len && htx_get_tail_type(htx) == HTX_BLK_DATA) {
+ /* When htx tail type == HTX_BLK_DATA, no need to take care
+ * of special blocks like HTX_BLK_EOT.
+ * We simply truncate after offset
+ * (truncate targeted blk and discard the following ones)
+ */
htx_truncate(htx, offset);
ret = len;
goto end;
@@ -6493,20 +6498,35 @@
htxret = htx_find_offset(htx, offset);
blk = htxret.blk;
if (htxret.ret) {
+ /* dealing with offset: we need to trim targeted blk */
struct ist v;
if (htx_get_blk_type(blk) != HTX_BLK_DATA)
goto end;
+
v = htx_get_blk_value(htx, blk);
v.ptr += htxret.ret;
+ v.len -= htxret.ret;
+
v = isttrim(v, len);
+ /* trimming data in blk: discard everything after the offset
+ * (replace 'v' with 'IST_NULL')
+ */
blk = htx_replace_blk_value(htx, blk, v, IST_NULL);
+ if (blk && v.len < len) {
+ /* In this case, caller wants to keep removing data,
+ * but we need to spare current blk
+ * because it was already trimmed
+ */
+ blk = htx_get_next_blk(htx, blk);
+ }
len -= v.len;
ret += v.len;
}
while (blk && len) {
+ /* there is more data that needs to be discarded */
enum htx_blk_type type = htx_get_blk_type(blk);
uint32_t sz = htx_get_blksz(blk);
@@ -6516,6 +6536,9 @@
case HTX_BLK_DATA:
if (len < sz) {
+ /* don't discard whole blk, only part of it
+ * (from the beginning)
+ */
htx_cut_data_blk(htx, blk, len);
ret += len;
goto end;
@@ -6523,6 +6546,7 @@
break;
default:
+ /* HTX_BLK_EOT blk won't be removed */
goto end;
}