diff --git a/deps/linenoise/README.markdown b/deps/linenoise/README.markdown index 1afea2ae6..b3752da16 100644 --- a/deps/linenoise/README.markdown +++ b/deps/linenoise/README.markdown @@ -108,7 +108,7 @@ to search and re-edit already inserted lines of text. The followings are the history API calls: - int linenoiseHistoryAdd(const char *line); + int linenoiseHistoryAdd(const char *line, int is_sensitive); int linenoiseHistorySetMaxLen(int len); int linenoiseHistorySave(const char *filename); int linenoiseHistoryLoad(const char *filename); diff --git a/deps/linenoise/linenoise.c b/deps/linenoise/linenoise.c index dd86abe86..75306390e 100644 --- a/deps/linenoise/linenoise.c +++ b/deps/linenoise/linenoise.c @@ -134,6 +134,8 @@ static int atexit_registered = 0; /* Register atexit just 1 time. */ static int history_max_len = LINENOISE_DEFAULT_HISTORY_MAX_LEN; static int history_len = 0; static char **history = NULL; +static int *history_sensitive = NULL; /* An array records whether each line in + * history is sensitive. */ /* The linenoiseState structure represents the state during line editing. * We pass this state to functions implementing specific editing @@ -177,7 +179,7 @@ enum KEY_ACTION{ }; static void linenoiseAtExit(void); -int linenoiseHistoryAdd(const char *line); +int linenoiseHistoryAdd(const char *line, int is_sensitive); static void refreshLine(struct linenoiseState *l); /* Debugging macro. */ @@ -818,7 +820,7 @@ static int linenoiseEdit(int stdin_fd, int stdout_fd, char *buf, size_t buflen, /* The latest history entry is always our current buffer, that * initially is just an empty string. */ - linenoiseHistoryAdd(""); + linenoiseHistoryAdd("", 0); if (write(l.ofd,prompt,l.plen) == -1) return -1; while(1) { @@ -1112,6 +1114,7 @@ static void freeHistory(void) { for (j = 0; j < history_len; j++) free(history[j]); free(history); + free(history_sensitive); } } @@ -1128,7 +1131,7 @@ static void linenoiseAtExit(void) { * histories, but will work well for a few hundred of entries. * * Using a circular buffer is smarter, but a bit more complex to handle. */ -int linenoiseHistoryAdd(const char *line) { +int linenoiseHistoryAdd(const char *line, int is_sensitive) { char *linecopy; if (history_max_len == 0) return 0; @@ -1137,7 +1140,14 @@ int linenoiseHistoryAdd(const char *line) { if (history == NULL) { history = malloc(sizeof(char*)*history_max_len); if (history == NULL) return 0; + history_sensitive = malloc(sizeof(int)*history_max_len); + if (history_sensitive == NULL) { + free(history); + history = NULL; + return 0; + } memset(history,0,(sizeof(char*)*history_max_len)); + memset(history_sensitive,0,(sizeof(int)*history_max_len)); } /* Don't add duplicated lines. */ @@ -1150,9 +1160,11 @@ int linenoiseHistoryAdd(const char *line) { if (history_len == history_max_len) { free(history[0]); memmove(history,history+1,sizeof(char*)*(history_max_len-1)); + memmove(history_sensitive,history_sensitive+1,sizeof(int)*(history_max_len-1)); history_len--; } history[history_len] = linecopy; + history_sensitive[history_len] = is_sensitive; history_len++; return 1; } @@ -1163,6 +1175,7 @@ int linenoiseHistoryAdd(const char *line) { * than the amount of items already inside the history. */ int linenoiseHistorySetMaxLen(int len) { char **new; + int *new_sensitive; if (len < 1) return 0; if (history) { @@ -1170,6 +1183,11 @@ int linenoiseHistorySetMaxLen(int len) { new = malloc(sizeof(char*)*len); if (new == NULL) return 0; + new_sensitive = malloc(sizeof(int)*len); + if (new_sensitive == NULL) { + free(new); + return 0; + } /* If we can't copy everything, free the elements we'll not use. */ if (len < tocopy) { @@ -1179,9 +1197,13 @@ int linenoiseHistorySetMaxLen(int len) { tocopy = len; } memset(new,0,sizeof(char*)*len); + memset(new_sensitive,0,sizeof(int)*len); memcpy(new,history+(history_len-tocopy), sizeof(char*)*tocopy); + memcpy(new_sensitive,history_sensitive+(history_len-tocopy), sizeof(int)*tocopy); free(history); + free(history_sensitive); history = new; + history_sensitive = new_sensitive; } history_max_len = len; if (history_len > history_max_len) @@ -1201,7 +1223,7 @@ int linenoiseHistorySave(const char *filename) { if (fp == NULL) return -1; fchmod(fileno(fp),S_IRUSR|S_IWUSR); for (j = 0; j < history_len; j++) - fprintf(fp,"%s\n",history[j]); + if (!history_sensitive[j]) fprintf(fp,"%s\n",history[j]); fclose(fp); return 0; } @@ -1223,7 +1245,7 @@ int linenoiseHistoryLoad(const char *filename) { p = strchr(buf,'\r'); if (!p) p = strchr(buf,'\n'); if (p) *p = '\0'; - linenoiseHistoryAdd(buf); + linenoiseHistoryAdd(buf, 0); } fclose(fp); return 0; diff --git a/deps/linenoise/linenoise.h b/deps/linenoise/linenoise.h index 6dfee73bc..beac6df46 100644 --- a/deps/linenoise/linenoise.h +++ b/deps/linenoise/linenoise.h @@ -58,7 +58,7 @@ void linenoiseAddCompletion(linenoiseCompletions *, const char *); char *linenoise(const char *prompt); void linenoiseFree(void *ptr); -int linenoiseHistoryAdd(const char *line); +int linenoiseHistoryAdd(const char *line, int is_sensitive); int linenoiseHistorySetMaxLen(int len); int linenoiseHistorySave(const char *filename); int linenoiseHistoryLoad(const char *filename); diff --git a/src/redis-cli.c b/src/redis-cli.c index f18961eaf..b9f44bb15 100644 --- a/src/redis-cli.c +++ b/src/redis-cli.c @@ -3394,7 +3394,7 @@ static void repl(void) { if (argv == NULL) { printf("Invalid argument(s)\n"); fflush(stdout); - if (history) linenoiseHistoryAdd(line); + if (history) linenoiseHistoryAdd(line, 0); if (historyfile) linenoiseHistorySave(historyfile); linenoiseFree(line); continue; @@ -3420,10 +3420,11 @@ static void repl(void) { repeat = 1; } - if (!isSensitiveCommand(argc - skipargs, argv + skipargs)) { - if (history) linenoiseHistoryAdd(line); - if (historyfile) linenoiseHistorySave(historyfile); - } + /* Always keep in-memory history. But for commands with sensitive information, + * avoid writing them to the history file. */ + int is_sensitive = isSensitiveCommand(argc - skipargs, argv + skipargs); + if (history) linenoiseHistoryAdd(line, is_sensitive); + if (!is_sensitive && historyfile) linenoiseHistorySave(historyfile); if (strcasecmp(argv[0],"quit") == 0 || strcasecmp(argv[0],"exit") == 0)