diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/aof.c | 37 |
1 files changed, 29 insertions, 8 deletions
@@ -577,6 +577,14 @@ struct redisClient *createFakeClient(void) { return c; } +void freeFakeClientArgv(struct redisClient *c) { + int j; + + for (j = 0; j < c->argc; j++) + decrRefCount(c->argv[j]); + zfree(c->argv); +} + void freeFakeClient(struct redisClient *c) { sdsfree(c->querybuf); listRelease(c->reply); @@ -639,14 +647,30 @@ int loadAppendOnlyFile(char *filename) { if (argc < 1) goto fmterr; argv = zmalloc(sizeof(robj*)*argc); + fakeClient->argc = argc; + fakeClient->argv = argv; + for (j = 0; j < argc; j++) { - if (fgets(buf,sizeof(buf),fp) == NULL) goto readerr; + if (fgets(buf,sizeof(buf),fp) == NULL) { + fakeClient->argc = j; /* Free up to j-1. */ + freeFakeClientArgv(fakeClient); + goto readerr; + } if (buf[0] != '$') goto fmterr; len = strtol(buf+1,NULL,10); argsds = sdsnewlen(NULL,len); - if (len && fread(argsds,len,1,fp) == 0) goto readerr; + if (len && fread(argsds,len,1,fp) == 0) { + sdsfree(argsds); + fakeClient->argc = j; /* Free up to j-1. */ + freeFakeClientArgv(fakeClient); + goto readerr; + } argv[j] = createObject(REDIS_STRING,argsds); - if (fread(buf,2,1,fp) == 0) goto readerr; /* discard CRLF */ + if (fread(buf,2,1,fp) == 0) { + fakeClient->argc = j+1; /* Free up to j. */ + freeFakeClientArgv(fakeClient); + goto readerr; /* discard CRLF */ + } } /* Command lookup */ @@ -655,9 +679,8 @@ int loadAppendOnlyFile(char *filename) { redisLog(REDIS_WARNING,"Unknown command '%s' reading the append only file", (char*)argv[0]->ptr); exit(1); } + /* Run the command in the context of a fake client */ - fakeClient->argc = argc; - fakeClient->argv = argv; cmd->proc(fakeClient); /* The fake client should not have a reply */ @@ -667,9 +690,7 @@ int loadAppendOnlyFile(char *filename) { /* Clean up. Command code may have changed argv/argc so we use the * argv/argc of the client instead of the local variables. */ - for (j = 0; j < fakeClient->argc; j++) - decrRefCount(fakeClient->argv[j]); - zfree(fakeClient->argv); + freeFakeClientArgv(fakeClient); } /* This point can only be reached when EOF is reached without errors. |