ocornut/imgui

ImGuiInputTextCallbackData::InsertChars sets CursorPos incorrectly

Closed this issue · 1 comments

Version/Branch of Dear ImGui:

Latest docking

Back-ends:

any backend

Compiler, OS:

Any platorm

Full config/build information:

No response

Details:

My Issue/Question:
There are two issues:

  1. When ImGuiInputTextCallbackData::CursorPos is set incorrectly (pointing past BufTextLen), ImGui::InputText stucks in an endless loop. This issue has appeared somewhat recently, it didn't get stuck two months ago.
  2. The CursorPos update code in the ImGuiInputTextCallbackData::InsertChars function doesn't check if BufTextLen has changed, thus setting it incorrectly.
    if (CursorPos >= pos)
        CursorPos += new_text_len;

This leads to CursorPos pointing past BufTextLen, which results in ImGui::InputText entering an endless loop during string size calculation.
I strongly believe this is somewhat that should be fixed on ImGui side.

Screenshots/Video:

No response

Minimal, Complete and Verifiable Example code:

char edit_string[1024]{}; // brace-initialized to zero
strcpy(edit_string, "testing1234567899"); // the bug appears when inserting chars into previously filled string.

constexpr auto callback = [](ImGuiInputTextCallbackData* data)
{
	std::string out_str{ "test" };
	data->BufTextLen = 0;
	//data->CursorPos = 0; // <-- the manual fix for the problem
	data->InsertChars(0, out_str.c_str(), out_str.c_str() + out_str.size());
	// because we don't reset the cursor pos ourselves, it now points past the string size.
	return 0;
};

constexpr ImGuiInputTextFlags input_text_flags =
    ImGuiInputTextFlags_CallbackCompletion | ImGuiInputTextFlags_CallbackHistory |
    ImGuiInputTextFlags_EnterReturnsTrue | ImGuiInputTextFlags_EscapeClearsAll;

ImGui::InputText("##input", edit_string, std::size(edit_string), input_text_flags, callback, nullptr);
// Just press Tab or keyboard arrows now to trigger the callback

Thank you for your report! This is now fixed with 2b770a0.

Note that it already behaved incorrectly before: the cursor position would appear incorrectly and gets "fixed" by subsequent action.

Simplified repro:

static char buf[1024] = "testing1234567899";
auto callback = [](ImGuiInputTextCallbackData* data)
{
    data->BufTextLen = 0;
    //data->CursorPos = 0; // <-- the manual fix for the problem
    data->InsertChars(0, "test");
    // because we don't reset the cursor pos ourselves, it now points past the string size.
    return 0;
};
constexpr ImGuiInputTextFlags input_text_flags = ImGuiInputTextFlags_CallbackCompletion | ImGuiInputTextFlags_CallbackHistory | ImGuiInputTextFlags_EnterReturnsTrue | ImGuiInputTextFlags_EscapeClearsAll;
ImGui::InputText("##input", buf, IM_ARRAYSIZE(buf), input_text_flags, callback, nullptr);
// Just press Tab or keyboard arrows now to trigger the callback