BUG/MEDIUM: cli: fix once for all the problem of missing trailing LFs

Some commands are still missing their trailing LF, and very few were even
already spotted in the past emitting more than one. The risk of missing
this LF is particularly high, especially when tests are run in non-
interactive mode where the output looks good at first glance. The problem
is that once run in interactive mode, the missing empty line makes the
command not being complete, and scripts can wait forever.

Let's tackle the problem at its root: messages emitted at the end must
always end with an LF and we know some miss it. Thus, in cli_output_msg()
we now start by removing the trailing LFs from the string, and we always
add exactly one. This way the trailing LF added by correct functions are
silently ignored and all functions are now correct.

This would need to be progressively backported to all supported versions
in order to address them all at once, though the risk of breaking a legacy
script relying on the wrong output is never zero. At first it should at
least go as far as the lastest LTS (2.8), and maybe another one depending
on user demands. Note that it also requires previous patch ("BUG/MINOR:
vars/cli: fix missing LF after "get var" output") because it fixes a test
for a bogus output for "get var" in a VTC.

(cherry picked from commit 6219a58d285060b1eaa33c4c56f89a37a33230a4)
Signed-off-by: Christopher Faulet <cfaulet@haproxy.com>
(cherry picked from commit 13dc860e2a1f2cad9dba956a851beb84a5bba1fe)
Signed-off-by: Willy Tarreau <w@1wt.eu>
diff --git a/src/cli.c b/src/cli.c
index 256094d..f1d5b5a 100644
--- a/src/cli.c
+++ b/src/cli.c
@@ -852,13 +852,14 @@
 static int cli_output_msg(struct appctx *appctx, const char *msg, int severity, int severity_output)
 {
 	struct buffer *tmp;
-
-	if (likely(severity_output == CLI_SEVERITY_NONE))
-		return applet_putstr(appctx, msg);
+	struct ist imsg;
 
 	tmp = get_trash_chunk();
 	chunk_reset(tmp);
 
+	if (likely(severity_output == CLI_SEVERITY_NONE))
+		goto send_it;
+
 	if (severity < 0 || severity > 7) {
 		ha_warning("socket command feedback with invalid severity %d", severity);
 		chunk_printf(tmp, "[%d]: ", severity);
@@ -875,7 +876,17 @@
 				ha_warning("Unrecognized severity output %d", severity_output);
 		}
 	}
-	chunk_appendf(tmp, "%s", msg);
+ send_it:
+	/* the vast majority of messages have their trailing LF but a few are
+	 * still missing it, and very rare ones might even have two. For this
+	 * reason, we'll first delete the trailing LFs if present, then
+	 * systematically append one.
+	 */
+	for (imsg = ist(msg); imsg.len > 0 && imsg.ptr[imsg.len - 1] == '\n'; imsg.len--)
+		;
+
+	chunk_istcat(tmp, imsg);
+	chunk_istcat(tmp, ist("\n"));
 
 	return applet_putchk(appctx, tmp);
 }