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
| 2312 | * command is in RESP format, so the first byte in the command is found |
| 2313 | * to be '*'. Otherwise for inline commands processInlineBuffer() is called. */ |
| 2314 | int processMultibulkBuffer(client *c) { |
| 2315 | char *newline = NULL; |
| 2316 | int ok; |
| 2317 | long long ll; |
| 2318 | |
| 2319 | if (c->multibulklen == 0) { |
| 2320 | /* The client should have been reset */ |
| 2321 | serverAssertWithInfo(c,NULL,c->argc == 0); |
| 2322 | |
| 2323 | /* Multi bulk length cannot be read without a \r\n */ |
| 2324 | newline = strchr(c->querybuf+c->qb_pos,'\r'); |
| 2325 | if (newline == NULL) { |
| 2326 | if (sdslen(c->querybuf)-c->qb_pos > PROTO_INLINE_MAX_SIZE) { |
| 2327 | addReplyError(c,"Protocol error: too big mbulk count string"); |
| 2328 | setProtocolError("too big mbulk count string",c); |
| 2329 | } |
| 2330 | return C_ERR; |
| 2331 | } |
| 2332 | |
| 2333 | /* Buffer should also contain \n */ |
| 2334 | if (newline-(c->querybuf+c->qb_pos) > (ssize_t)(sdslen(c->querybuf)-c->qb_pos-2)) |
| 2335 | return C_ERR; |
| 2336 | |
| 2337 | /* We know for sure there is a whole line since newline != NULL, |
| 2338 | * so go ahead and find out the multi bulk length. */ |
| 2339 | serverAssertWithInfo(c,NULL,c->querybuf[c->qb_pos] == '*'); |
| 2340 | ok = string2ll(c->querybuf+1+c->qb_pos,newline-(c->querybuf+1+c->qb_pos),&ll); |
| 2341 | if (!ok || ll > 1024*1024) { |
| 2342 | addReplyError(c,"Protocol error: invalid multibulk length"); |
| 2343 | setProtocolError("invalid mbulk count",c); |
| 2344 | return C_ERR; |
| 2345 | } else if (ll > 10 && authRequired(c)) { |
| 2346 | addReplyError(c, "Protocol error: unauthenticated multibulk length"); |
| 2347 | setProtocolError("unauth mbulk count", c); |
| 2348 | return C_ERR; |
| 2349 | } |
| 2350 | |
| 2351 | c->qb_pos = (newline-c->querybuf)+2; |
| 2352 | |
| 2353 | if (ll <= 0) return C_OK; |
| 2354 | |
| 2355 | c->multibulklen = ll; |
| 2356 | |
| 2357 | /* Setup argv array on client structure */ |
| 2358 | c->vecqueuedcmd.emplace_back(c->multibulklen); |
| 2359 | } |
| 2360 | |
| 2361 | serverAssertWithInfo(c,NULL,c->multibulklen > 0); |
| 2362 | while(c->multibulklen) { |
| 2363 | /* Read bulk length if unknown */ |
| 2364 | if (c->bulklen == -1) { |
| 2365 | newline = strchr(c->querybuf+c->qb_pos,'\r'); |
| 2366 | if (newline == NULL) { |
| 2367 | if (sdslen(c->querybuf)-c->qb_pos > PROTO_INLINE_MAX_SIZE) { |
| 2368 | addReplyError(c, |
| 2369 | "Protocol error: too big bulk count string"); |
| 2370 | setProtocolError("too big bulk count string",c); |
| 2371 | return C_ERR; |
no test coverage detected