Process the query buffer for client 'c', setting up the client argument * vector for command execution. Returns C_OK if after running the function * the client has a well-formed ready to be processed command, otherwise * C_ERR if there is still to read more buffer to get the full command. * The function also returns C_ERR when there is a protocol error: in such a * case the client structure i
| 1839 | * command is in RESP format, so the first byte in the command is found |
| 1840 | * to be '*'. Otherwise for inline commands processInlineBuffer() is called. */ |
| 1841 | int processMultibulkBuffer(client *c) { |
| 1842 | char *newline = NULL; |
| 1843 | int ok; |
| 1844 | long long ll; |
| 1845 | |
| 1846 | if (c->multibulklen == 0) { |
| 1847 | /* The client should have been reset */ |
| 1848 | serverAssertWithInfo(c,NULL,c->argc == 0); |
| 1849 | |
| 1850 | /* Multi bulk length cannot be read without a \r\n */ |
| 1851 | newline = strchr(c->querybuf+c->qb_pos,'\r'); |
| 1852 | if (newline == NULL) { |
| 1853 | if (sdslen(c->querybuf)-c->qb_pos > PROTO_INLINE_MAX_SIZE) { |
| 1854 | addReplyError(c,"Protocol error: too big mbulk count string"); |
| 1855 | setProtocolError("too big mbulk count string",c); |
| 1856 | } |
| 1857 | return C_ERR; |
| 1858 | } |
| 1859 | |
| 1860 | /* Buffer should also contain \n */ |
| 1861 | if (newline-(c->querybuf+c->qb_pos) > (ssize_t)(sdslen(c->querybuf)-c->qb_pos-2)) |
| 1862 | return C_ERR; |
| 1863 | |
| 1864 | /* We know for sure there is a whole line since newline != NULL, |
| 1865 | * so go ahead and find out the multi bulk length. */ |
| 1866 | serverAssertWithInfo(c,NULL,c->querybuf[c->qb_pos] == '*'); |
| 1867 | ok = string2ll(c->querybuf+1+c->qb_pos,newline-(c->querybuf+1+c->qb_pos),&ll); |
| 1868 | if (!ok || ll > 1024*1024) { |
| 1869 | addReplyError(c,"Protocol error: invalid multibulk length"); |
| 1870 | setProtocolError("invalid mbulk count",c); |
| 1871 | return C_ERR; |
| 1872 | } else if (ll > 10 && authRequired(c)) { |
| 1873 | addReplyError(c, "Protocol error: unauthenticated multibulk length"); |
| 1874 | setProtocolError("unauth mbulk count", c); |
| 1875 | return C_ERR; |
| 1876 | } |
| 1877 | |
| 1878 | c->qb_pos = (newline-c->querybuf)+2; |
| 1879 | |
| 1880 | if (ll <= 0) return C_OK; |
| 1881 | |
| 1882 | c->multibulklen = ll; |
| 1883 | |
| 1884 | /* Setup argv array on client structure */ |
| 1885 | if (c->argv) zfree(c->argv); |
| 1886 | c->argv = zmalloc(sizeof(robj*)*c->multibulklen); |
| 1887 | c->argv_len_sum = 0; |
| 1888 | } |
| 1889 | |
| 1890 | serverAssertWithInfo(c,NULL,c->multibulklen > 0); |
| 1891 | while(c->multibulklen) { |
| 1892 | /* Read bulk length if unknown */ |
| 1893 | if (c->bulklen == -1) { |
| 1894 | newline = strchr(c->querybuf+c->qb_pos,'\r'); |
| 1895 | if (newline == NULL) { |
| 1896 | if (sdslen(c->querybuf)-c->qb_pos > PROTO_INLINE_MAX_SIZE) { |
| 1897 | addReplyError(c, |
| 1898 | "Protocol error: too big bulk count string"); |
no test coverage detected