BUG/MINOR: server: Be sure to cut the last parsed field of a server-state line
If a line of a server-state file has too many fields, the last one is not
cut on the first following space, as all other fileds. It contains all the
end of the line. It is not the expected behavior. So, now, we cut it on the
next following space, if any. The parsing loop was slighly rewritten.
Note that for now there is no error reported if the line is too long.
This patch may be backported at least as far as 2.1. On 2.0 and prior the
code is not the same. The line parsing is inlined in apply_server_state()
function.
(cherry picked from commit 868a5757e584431fafe713546c8ef8e799865476)
Signed-off-by: Christopher Faulet <cfaulet@haproxy.com>
(cherry picked from commit 8c5b974f282729abefb617671e7c5910347555fa)
Signed-off-by: Christopher Faulet <cfaulet@haproxy.com>
(cherry picked from commit 61cdb0f1c4ddbe8b7b4882dda767f57d6cf5ecd3)
Signed-off-by: Christopher Faulet <cfaulet@haproxy.com>
(cherry picked from commit 5cea0fe0d7254b30b5318fc9149ad044ba93319b)
[cf: Context adjustment]
Signed-off-by: Christopher Faulet <cfaulet@haproxy.com>
diff --git a/src/server.c b/src/server.c
index 96144b0..3c3876e 100644
--- a/src/server.c
+++ b/src/server.c
@@ -3458,50 +3458,54 @@
/* we're now ready to move the line into *srv_params[] */
memset(params, 0, SRV_STATE_FILE_MAX_FIELDS * sizeof(*params));
memset(srv_params, 0, SRV_STATE_FILE_MAX_FIELDS * sizeof(*srv_params));
- params[0] = cur;
- arg = 1;
+
+ arg = 0;
srv_arg = 0;
while (*cur && arg < SRV_STATE_FILE_MAX_FIELDS) {
- if (isspace(*cur)) {
- *cur = '\0';
+ /* Search begining of the current field */
+ while (isspace((unsigned char)*cur)) {
++cur;
- while (isspace(*cur))
- ++cur;
- switch (version) {
- case 1:
- /*
- * srv_addr: params[4] => srv_params[0]
- * srv_op_state: params[5] => srv_params[1]
- * srv_admin_state: params[6] => srv_params[2]
- * srv_uweight: params[7] => srv_params[3]
- * srv_iweight: params[8] => srv_params[4]
- * srv_last_time_change: params[9] => srv_params[5]
- * srv_check_status: params[10] => srv_params[6]
- * srv_check_result: params[11] => srv_params[7]
- * srv_check_health: params[12] => srv_params[8]
- * srv_check_state: params[13] => srv_params[9]
- * srv_agent_state: params[14] => srv_params[10]
- * bk_f_forced_id: params[15] => srv_params[11]
- * srv_f_forced_id: params[16] => srv_params[12]
- * srv_fqdn: params[17] => srv_params[13]
- * srv_port: params[18] => srv_params[14]
- * srvrecord: params[19] => srv_params[15]
- */
- if (arg >= 4) {
- srv_params[srv_arg] = cur;
- ++srv_arg;
- }
- break;
- }
+ if (!*cur)
+ goto end_loop;
+ }
- params[arg] = cur;
- ++arg;
+ /*
+ * v1
+ * srv_addr: params[4] => srv_params[0]
+ * srv_op_state: params[5] => srv_params[1]
+ * srv_admin_state: params[6] => srv_params[2]
+ * srv_uweight: params[7] => srv_params[3]
+ * srv_iweight: params[8] => srv_params[4]
+ * srv_last_time_change: params[9] => srv_params[5]
+ * srv_check_status: params[10] => srv_params[6]
+ * srv_check_result: params[11] => srv_params[7]
+ * srv_check_health: params[12] => srv_params[8]
+ * srv_check_state: params[13] => srv_params[9]
+ * srv_agent_state: params[14] => srv_params[10]
+ * bk_f_forced_id: params[15] => srv_params[11]
+ * srv_f_forced_id: params[16] => srv_params[12]
+ * srv_fqdn: params[17] => srv_params[13]
+ * srv_port: params[18] => srv_params[14]
+ * srvrecord: params[19] => srv_params[15]
+ */
+ if (version == 1 && arg >= 4) {
+ srv_params[srv_arg] = cur;
+ ++srv_arg;
}
- else {
+ params[arg] = cur;
+ ++arg;
+
+ /* Search end of the current field: first space or \0 */
+ /* Search begining of the current field */
+ while (!isspace((unsigned char)*cur)) {
++cur;
+ if (!*cur)
+ goto end_loop;
}
+ *cur++ = '\0';
}
+ end_loop:
/* if line is incomplete line, then ignore it.
* otherwise, update useful flags */
switch (version) {