redis-cli --pipe: send final ECHO in a safer way.

If the protocol read from stdin happened to contain grabage (invalid
random chars), in the previous implementation it was possible to end
with something like:

dksfjdksjflskfjl*2\r\n$4\r\nECHO....

That is invalid as the *2 should start into a new line. Now we prefix
the ECHO with a CRLF that has no effects on the server but prevents this
issues most of the times.

Of course if the offending wrong sequence is something like:

$3248772349\r\n

No one is going to save us as Redis will wait for data in the context of
a big argument, so this fix does not cover all the cases.

This partially fixes issue #681.
This commit is contained in:
antirez 2013-07-03 11:59:44 +02:00
parent 4a6701d7ec
commit 703cd738dc

View File

@ -1204,8 +1204,12 @@ static void pipeMode(void) {
ssize_t nread = read(STDIN_FILENO,obuf,sizeof(obuf)); ssize_t nread = read(STDIN_FILENO,obuf,sizeof(obuf));
if (nread == 0) { if (nread == 0) {
/* The ECHO sequence starts with a "\r\n" so that if there
* is garbage in the protocol we read from stdin, the ECHO
* will likely still be properly formatted.
* CRLF is ignored by Redis, so it has no effects. */
char echo[] = char echo[] =
"*2\r\n$4\r\nECHO\r\n$20\r\n01234567890123456789\r\n"; "\r\n*2\r\n$4\r\nECHO\r\n$20\r\n01234567890123456789\r\n";
int j; int j;
eof = 1; eof = 1;
@ -1214,7 +1218,7 @@ static void pipeMode(void) {
* to make sure everything was read from the server. */ * to make sure everything was read from the server. */
for (j = 0; j < 20; j++) for (j = 0; j < 20; j++)
magic[j] = rand() & 0xff; magic[j] = rand() & 0xff;
memcpy(echo+19,magic,20); memcpy(echo+21,magic,20);
memcpy(obuf,echo,sizeof(echo)-1); memcpy(obuf,echo,sizeof(echo)-1);
obuf_len = sizeof(echo)-1; obuf_len = sizeof(echo)-1;
obuf_pos = 0; obuf_pos = 0;