Repository: valkey-io/valkey
File: src/networking.c (C)

Code before:
    int ok;
    long long ll;
    int is_replicated = c->read_flags & READ_FLAGS_REPLICATED;
    int auth_required = c->read_flags & READ_FLAGS_AUTH_REQUIRED;

    if (c->multibulklen == 0) {
        /* The client (argc) should have been reset */
        serverAssertWithInfo(c, NULL, *argc == 0);

        /* Multi bulk length cannot be read without a \r\n */
        newline = memchr(c->querybuf + c->qb_pos, '\r', sdslen(c->querybuf) - c->qb_pos);
        if (newline == NULL) {
            if (sdslen(c->querybuf) - c->qb_pos > PROTO_INLINE_MAX_SIZE) {
                return READ_FLAGS_ERROR_BIG_MULTIBULK;
            }
            return 0;
        }

        /* Buffer should also contain \n */
        if (newline - (c->querybuf + c->qb_pos) > (ssize_t)(sdslen(c->querybuf) - c->qb_pos - 2)) return 0;

        /* Check that what follows \r is a real \n */
        if (newline[1] != '\n') {
            return READ_FLAGS_ERROR_INVALID_CRLF;
        }

        /* We know for sure there is a whole line since newline != NULL,
         * so go ahead and find out the multi bulk length. */
        serverAssertWithInfo(c, NULL, c->querybuf[c->qb_pos] == '*');
        size_t multibulklen_slen = newline - (c->querybuf + 1 + c->qb_pos);
        ok = string2ll(c->querybuf + 1 + c->qb_pos, multibulklen_slen, &ll);
        if (!ok || ll > INT_MAX) {
            return READ_FLAGS_ERROR_INVALID_MULTIBULK_LEN;
        } else if (ll > 10 && auth_required) {
            return READ_FLAGS_ERROR_UNAUTHENTICATED_MULTIBULK_LEN;
        }

        c->qb_pos = (newline - c->querybuf) + 2;

        if (ll <= 0) {
            return READ_FLAGS_PARSING_NEGATIVE_MBULK_LEN;
        }

        c->multibulklen = ll;
        c->bulklen = -1;

        /* Setup argv array */
        if (*argv) zfree(*argv);
        *argv_len = min(c->multibulklen, 1024);
        *argv = zmalloc(sizeof(robj *) * *argv_len);
        *argv_len_sum = 0;

Review comment (refactor):
So the first check is for a case when we read up to \r but the \n is not yet read into the buffer right? Maybe we should have made a similar check like we do for inline protocol and just search for the \n and not \r?
not sure if that would simplify things but it seems like it would make the check in line 3490 more accurate...

Code after:
    int ok;
    long long ll;
    int is_replicated = c->read_flags & READ_FLAGS_REPLICATED;
    int auth_required = c->read_flags & READ_FLAGS_AUTH_REQUIRED;

    if (c->multibulklen == 0) {
        /* The client (argc) should have been reset */
        serverAssertWithInfo(c, NULL, *argc == 0);

        /* Multi bulk length cannot be read without a \r\n */
        newline = memchr(c->querybuf + c->qb_pos, '\r', sdslen(c->querybuf) - c->qb_pos);
        if (newline == NULL) {
            if (sdslen(c->querybuf) - c->qb_pos > PROTO_INLINE_MAX_SIZE) {
                return READ_FLAGS_ERROR_BIG_MULTIBULK;
            }
            return 0;
        }

        /* Buffer should also contain \n */
        if (newline - (c->querybuf + c->qb_pos) > (ssize_t)(sdslen(c->querybuf) - c->qb_pos - 2)) return 0;

        /* Check that what follows \r is a real \n */
        if (unlikely(newline[1] != '\n')) {
            return READ_FLAGS_ERROR_INVALID_CRLF;
        }

        /* We know for sure there is a whole line since newline != NULL,
         * so go ahead and find out the multi bulk length. */
        serverAssertWithInfo(c, NULL, c->querybuf[c->qb_pos] == '*');
        size_t multibulklen_slen = newline - (c->querybuf + 1 + c->qb_pos);
        ok = string2ll(c->querybuf + 1 + c->qb_pos, multibulklen_slen, &ll);
        if (!ok || ll > INT_MAX) {
            return READ_FLAGS_ERROR_INVALID_MULTIBULK_LEN;
        } else if (ll > 10 && auth_required) {
            return READ_FLAGS_ERROR_UNAUTHENTICATED_MULTIBULK_LEN;
        }

        c->qb_pos = (newline - c->querybuf) + 2;

        if (ll <= 0) {
            return READ_FLAGS_PARSING_NEGATIVE_MBULK_LEN;
        }

        c->multibulklen = ll;
        c->bulklen = -1;

        /* Setup argv array */
        if (*argv) zfree(*argv);
        *argv_len = min(c->multibulklen, 1024);
        *argv = zmalloc(sizeof(robj *) * *argv_len);
        *argv_len_sum = 0;