From: Nir Soffer Date: Mon, 10 Jul 2017 21:06:57 +0000 (+0300) Subject: [2.7] bpo-29854: Fix segfault in call_readline() (GH-728) X-Git-Tag: v2.7.14rc1~52 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=bfa4fe4f39dd8b5ce1a0b649cedd36857859081a;p=thirdparty%2FPython%2Fcpython.git [2.7] bpo-29854: Fix segfault in call_readline() (GH-728) If history-length is set in .inputrc, and the history file is double the history size (or more), history_get(N) returns NULL, and python segfaults. Fix that by checking for NULL return value. It seems that the root cause is incorrect handling of bigger history in readline, but Python should not segfault even if readline returns unexpected value. This issue affects only GNU readline. When using libedit emulation system history size option does not work. This is a backport of the actual fix from master without the test, since the test depends on new run_pty() helper which is not available in 2.7. --- diff --git a/Misc/NEWS.d/next/Library/2017-07-07-02-18-57.bpo-29854.J8wKb_.rst b/Misc/NEWS.d/next/Library/2017-07-07-02-18-57.bpo-29854.J8wKb_.rst new file mode 100644 index 000000000000..5c439087dcb3 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2017-07-07-02-18-57.bpo-29854.J8wKb_.rst @@ -0,0 +1,2 @@ +Fix segfault in readline when using readline's history-size option. Patch +by Nir Soffer. diff --git a/Modules/readline.c b/Modules/readline.c index ad5903cfb51a..1e10dd708b99 100644 --- a/Modules/readline.c +++ b/Modules/readline.c @@ -1161,15 +1161,17 @@ call_readline(FILE *sys_stdin, FILE *sys_stdout, char *prompt) if (n > 0) { const char *line; int length = _py_get_history_length(); - if (length > 0) + if (length > 0) { + HIST_ENTRY *hist_ent; #ifdef __APPLE__ if (using_libedit_emulation) { /* handle older 0-based or newer 1-based indexing */ - line = history_get(length + libedit_history_start - 1)->line; + hist_ent = history_get(length + libedit_history_start - 1); } else #endif /* __APPLE__ */ - line = history_get(length)->line; - else + hist_ent = history_get(length); + line = hist_ent ? hist_ent->line : ""; + } else line = ""; if (strcmp(p, line)) add_history(p);