MINOR: cli: allow the semi-colon to be escaped on the CLI

Today I was working on an auto-update script for some ACLs, and found
that I couldn't load ACL entries with a semi-colon in them no matter
how I tried to escape it.

As such, I wrote this patch (this one is for 1.7dev, but it applies to
1.5 the same with just line numbers changed), which seems to allow me
to execute a command such as "add acl /etc/foo.lst foo\;bar" over the
socket. It's worth noting that stats_sock_parse_request() already uses
the backslash to escape spaces in words so it makes sense to use it as
well to escape the semi-colon.
This commit is contained in:
Chad Lavoie 2016-05-26 16:42:25 -04:00 committed by Willy Tarreau
parent 74967f60ec
commit e3f5031b51
2 changed files with 11 additions and 3 deletions

View File

@ -1239,6 +1239,9 @@ example :
# echo "show info;show stat;show table" | socat /var/run/haproxy stdio # echo "show info;show stat;show table" | socat /var/run/haproxy stdio
If a command needs to use a semi-colon (eg: in a value), it must be preceeded
by a backslash ('\').
The interactive mode displays a prompt ('>') and waits for commands to be The interactive mode displays a prompt ('>') and waits for commands to be
entered on the line, then processes them, and displays the prompt again to wait entered on the line, then processes them, and displays the prompt again to wait
for a new command. This mode is entered via the "prompt" command which must be for a new command. This mode is entered via the "prompt" command which must be

View File

@ -2656,15 +2656,20 @@ static void cli_io_handler(struct appctx *appctx)
continue; continue;
} }
/* seek for a possible semi-colon. If we find one, we /* seek for a possible unescaped semi-colon. If we find
* replace it with an LF and skip only this part. * one, we replace it with an LF and skip only this part.
*/ */
for (len = 0; len < reql; len++) for (len = 0; len < reql; len++) {
if (trash.str[len] == '\\') {
len++;
continue;
}
if (trash.str[len] == ';') { if (trash.str[len] == ';') {
trash.str[len] = '\n'; trash.str[len] = '\n';
reql = len + 1; reql = len + 1;
break; break;
} }
}
/* now it is time to check that we have a full line, /* now it is time to check that we have a full line,
* remove the trailing \n and possibly \r, then cut the * remove the trailing \n and possibly \r, then cut the