Skip to content

Commit 0544c78

Browse files
kevinfreiKevin Frei
andauthored
Fix a crash from character type confusion interaction with libedit (llvm#75388)
If you type `settings show <tab>` LLDB might crash, depending on the version of libedit you're compiled with, and whether you're compiled with `-DLLDB_EDITLINE_USE_WCHAR=0` (and depending on how the optimizer lays out the stack...) The issue has to do with trying to figure out whether the libedit `getchar` callback is supposed to read a wide or 8 bit character. In order to maintain backward compatibility, there's really no 'clean' way to do it. We just have to make sure that we're invoking el_[w]getc with a buffer that is as wide as the getchar callback (registered by the `SetGetCharacterFunction` function further down in `Editline.cpp`. So, it's 'fixed' with a comment, and a wider version of the 'reply' variable. Co-authored-by: Kevin Frei <[email protected]>
1 parent fed5644 commit 0544c78

File tree

2 files changed

+10
-2
lines changed

2 files changed

+10
-2
lines changed

lldb/include/lldb/Host/Editline.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -75,6 +75,8 @@ using EditLineCharType = char;
7575
// to wchar_t. It is not possible to detect differentiate between the two
7676
// versions exactly, but this is a pretty good approximation and allows us to
7777
// build against almost any editline version out there.
78+
// It does, however, require extra care when invoking el_getc, as the type
79+
// of the input is a single char buffer, but the callback will write a wchar_t.
7880
#if LLDB_EDITLINE_USE_WCHAR || defined(EL_CLIENTDATA) || LLDB_HAVE_EL_RFUNC_T
7981
using EditLineGetCharType = wchar_t;
8082
#else

lldb/source/Host/common/Editline.cpp

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -978,8 +978,14 @@ void Editline::DisplayCompletions(
978978
break;
979979

980980
fprintf(editline.m_output_file, "More (Y/n/a): ");
981-
char reply = 'n';
982-
int got_char = el_getc(editline.m_editline, &reply);
981+
// The type for the output and the type for the parameter are different,
982+
// to allow interoperability with older versions of libedit. The container
983+
// for the reply must be as wide as what our implementation is using,
984+
// but libedit may use a narrower type depending on the build
985+
// configuration.
986+
EditLineGetCharType reply = L'n';
987+
int got_char = el_wgetc(editline.m_editline,
988+
reinterpret_cast<EditLineCharType *>(&reply));
983989
// Check for a ^C or other interruption.
984990
if (editline.m_editor_status == EditorStatus::Interrupted) {
985991
editline.m_editor_status = EditorStatus::Editing;

0 commit comments

Comments
 (0)