Skip to content

Commit bdbb2b2

Browse files
committed
Fix 83efdce from overflowing buffer + make it a single undo records + comments (#3008)
1 parent 83efdce commit bdbb2b2

File tree

2 files changed

+25
-18
lines changed

2 files changed

+25
-18
lines changed

docs/CHANGELOG.txt

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -76,7 +76,8 @@ Other Changes:
7676
those improvements in 1.73 makes them unnecessary. (#2722, #2770). [@rokups]
7777
- ColorEdit: "Copy As" context-menu tool shows hex values with a '#' prefix instead of '0x'.
7878
- ColorEdit: "Copy As" content-menu tool shows hex values both with/without alpha when available.
79-
- InputText: Fix crash when executing undo action after clearing input with ESC (#3008). [@rokups]
79+
- InputText: Fix corruption or crash when executing undo after clearing input with ESC, as a
80+
byproduct we are allowing to later undo the revert with a CTRL+Z. (#3008).
8081
- MenuBar: Fix minor clipping issue where occasionally a menu text can overlap the right-most border.
8182
- Window: Fix SetNextWindowBgAlpha(1.0f) failing to override alpha component. (#3007) [@Albog]
8283
- Window: When testing for the presence of the ImGuiWindowFlags_NoBringToFrontOnFocus flag we

imgui_widgets.cpp

Lines changed: 23 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -3271,8 +3271,25 @@ static bool STB_TEXTEDIT_INSERTCHARS(STB_TEXTEDIT_STRING* obj, int pos, const Im
32713271
#define STB_TEXTEDIT_IMPLEMENTATION
32723272
#include "imstb_textedit.h"
32733273

3274+
// stb_textedit internally allows for a single undo record to do addition and deletion, but somehow, calling
3275+
// the stb_textedit_paste() function creates two separate records, so we perform it manually. (FIXME: Report to nothings/stb?)
3276+
static void stb_textedit_replace(STB_TEXTEDIT_STRING* str, STB_TexteditState* state, const STB_TEXTEDIT_CHARTYPE* text, int text_len)
3277+
{
3278+
stb_text_makeundo_replace(str, state, 0, str->CurLenW, text_len);
3279+
ImStb::STB_TEXTEDIT_DELETECHARS(str, 0, str->CurLenW);
3280+
if (text_len <= 0)
3281+
return;
3282+
if (ImStb::STB_TEXTEDIT_INSERTCHARS(str, 0, text, text_len))
3283+
{
3284+
state->cursor = text_len;
3285+
state->has_preferred_x = 0;
3286+
return;
3287+
}
3288+
IM_ASSERT(0); // Failed to insert character, normally shouldn't happen because of how we currently use stb_textedit_replace()
32743289
}
32753290

3291+
} // namespace ImStb
3292+
32763293
void ImGuiInputTextState::OnKeyPressed(int key)
32773294
{
32783295
stb_textedit_key(this, &Stb, key);
@@ -3826,27 +3843,16 @@ bool ImGui::InputTextEx(const char* label, const char* hint, char* buf, int buf_
38263843
// Restore initial value. Only return true if restoring to the initial value changes the current buffer contents.
38273844
if (!is_readonly && strcmp(buf, state->InitialTextA.Data) != 0)
38283845
{
3846+
// Push records into the undo stack so we can CTRL+Z the revert operation itself
38293847
apply_new_text = state->InitialTextA.Data;
38303848
apply_new_text_length = state->InitialTextA.Size - 1;
3831-
3832-
// Select all text
3833-
state->OnKeyPressed(STB_TEXTEDIT_K_TEXTSTART);
3834-
state->OnKeyPressed(STB_TEXTEDIT_K_TEXTEND | STB_TEXTEDIT_K_SHIFT);
3835-
3836-
// Paste converted text or empty buffer
3837-
if (state->InitialTextA.size() > 1)
3838-
{
3839-
ImVector<ImWchar> w_text;
3840-
const char* apply_new_text_end = apply_new_text + apply_new_text_length + 1;
3841-
w_text.resize(ImTextCountCharsFromUtf8(apply_new_text, apply_new_text_end));
3842-
ImTextStrFromUtf8(w_text.Data, w_text.Size, apply_new_text, apply_new_text_end);
3843-
ImStb::stb_textedit_paste(state, &state->Stb, w_text.Data, w_text.Size);
3844-
}
3845-
else
3849+
ImVector<ImWchar> w_text;
3850+
if (apply_new_text_length > 0)
38463851
{
3847-
ImWchar empty = 0;
3848-
ImStb::stb_textedit_paste(state, &state->Stb, &empty, 0);
3852+
w_text.resize(ImTextCountCharsFromUtf8(apply_new_text, apply_new_text + apply_new_text_length) + 1);
3853+
ImTextStrFromUtf8(w_text.Data, w_text.Size, apply_new_text, apply_new_text + apply_new_text_length);
38493854
}
3855+
stb_textedit_replace(state, &state->Stb, w_text.Data, (apply_new_text_length > 0) ? (w_text.Size - 1) : 0);
38503856
}
38513857
}
38523858

0 commit comments

Comments
 (0)