MCPcopy Create free account
hub / github.com/Snapchat/KeyDB / ldbReplParseCommand

Function ldbReplParseCommand

src/scripting.cpp:2137–2189  ·  view source on GitHub ↗

Expect a valid multi-bulk command in the debugging client query buffer. * On success the command is parsed and returned as an array of SDS strings, * otherwise NULL is returned and there is to read more buffer. */

Source from the content-addressed store, hash-verified

2135 * On success the command is parsed and returned as an array of SDS strings,
2136 * otherwise NULL is returned and there is to read more buffer. */
2137sds *ldbReplParseCommand(int *argcp, char** err) {
2138 static sds protocol_error = sdsnew("protocol error");
2139 sds *argv = NULL;
2140 int argc = 0;
2141 char *plen = NULL;
2142 if (sdslen(ldb.cbuf) == 0) return NULL;
2143
2144 /* Working on a copy is simpler in this case. We can modify it freely
2145 * for the sake of simpler parsing. */
2146 sds copy = sdsdup(ldb.cbuf);
2147 char *p = copy;
2148
2149 /* This Redis protocol parser is a joke... just the simplest thing that
2150 * works in this context. It is also very forgiving regarding broken
2151 * protocol. */
2152
2153 /* Seek and parse *<count>\r\n. */
2154 p = strchr(p,'*'); if (!p) goto protoerr;
2155 plen = p+1; /* Multi bulk len pointer. */
2156 p = strstr(p,"\r\n"); if (!p) goto keep_reading;
2157 *p = '\0'; p += 2;
2158 *argcp = atoi(plen);
2159 if (*argcp <= 0 || *argcp > 1024) goto protoerr;
2160
2161 /* Parse each argument. */
2162 argv = (sds*)zmalloc(sizeof(sds)*(*argcp), MALLOC_LOCAL);
2163 argc = 0;
2164 while(argc < *argcp) {
2165 /* reached the end but there should be more data to read */
2166 if (*p == '\0') goto keep_reading;
2167
2168 if (*p != '$') goto protoerr;
2169 plen = p+1; /* Bulk string len pointer. */
2170 p = strstr(p,"\r\n"); if (!p) goto keep_reading;
2171 *p = '\0'; p += 2;
2172 int slen = atoi(plen); /* Length of this arg. */
2173 if (slen <= 0 || slen > 1024) goto protoerr;
2174 if ((size_t)(p + slen + 2 - copy) > sdslen(copy) ) goto keep_reading;
2175 argv[argc++] = sdsnewlen(p,slen);
2176 p += slen; /* Skip the already parsed argument. */
2177 if (p[0] != '\r' || p[1] != '\n') goto protoerr;
2178 p += 2; /* Skip \r\n. */
2179 }
2180 sdsfree(copy);
2181 return argv;
2182
2183protoerr:
2184 *err = protocol_error;
2185keep_reading:
2186 sdsfreesplitres(argv,argc);
2187 sdsfree(copy);
2188 return NULL;
2189}
2190
2191/* Log the specified line in the Lua debugger output. */
2192void ldbLogSourceLine(int lnum) {

Callers 1

ldbReplFunction · 0.85

Calls 7

sdsnewFunction · 0.85
sdslenFunction · 0.85
sdsdupFunction · 0.85
zmallocFunction · 0.85
sdsnewlenFunction · 0.85
sdsfreeFunction · 0.85
sdsfreesplitresFunction · 0.85

Tested by

no test coverage detected