Browse Source

InputText: sanity checks to e.g. detect non zero-terminated buffers + removed a redundant strlen() call during activation.

ocornut 7 months ago
parent
commit
9b0e61aaaa
2 changed files with 6 additions and 1 deletions
  1. 2 0
      docs/CHANGELOG.txt
  2. 4 1
      imgui_widgets.cpp

+ 2 - 0
docs/CHANGELOG.txt

@@ -47,6 +47,8 @@ Other changes:
   were not applied when pasting from clipbard. (#8229)
   were not applied when pasting from clipbard. (#8229)
 - InputText: Fixed issue when activating a ReadOnly field when the underlying
 - InputText: Fixed issue when activating a ReadOnly field when the underlying
   value is being modified. (#8242)
   value is being modified. (#8242)
+- InputText: Added sanity check to detect some cases of passing a non
+  zero-terminated input buffer.
 - Drags: Added ImGuiSliderFlags_NoSpeedTweaks flag to disable keyboard
 - Drags: Added ImGuiSliderFlags_NoSpeedTweaks flag to disable keyboard
   modifiers altering the tweak speed. Useful if you want to alter tweak speed
   modifiers altering the tweak speed. Useful if you want to alter tweak speed
   yourself based on your own logic. (#8223)
   yourself based on your own logic. (#8223)

+ 4 - 1
imgui_widgets.cpp

@@ -4389,6 +4389,7 @@ void ImGui::InputTextDeactivateHook(ImGuiID id)
     else
     else
     {
     {
         IM_ASSERT(state->TextA.Data != 0);
         IM_ASSERT(state->TextA.Data != 0);
+        IM_ASSERT(state->TextA[state->TextLen] == 0);
         g.InputTextDeactivatedState.TextA.resize(state->TextLen + 1);
         g.InputTextDeactivatedState.TextA.resize(state->TextLen + 1);
         memcpy(g.InputTextDeactivatedState.TextA.Data, state->TextA.Data, state->TextLen + 1);
         memcpy(g.InputTextDeactivatedState.TextA.Data, state->TextA.Data, state->TextLen + 1);
     }
     }
@@ -4519,6 +4520,7 @@ bool ImGui::InputTextEx(const char* label, const char* hint, char* buf, int buf_
     if (init_reload_from_user_buf)
     if (init_reload_from_user_buf)
     {
     {
         int new_len = (int)strlen(buf);
         int new_len = (int)strlen(buf);
+        IM_ASSERT(new_len + 1 <= buf_size && "Is your input buffer properly zero-terminated?");
         state->WantReloadUserBuf = false;
         state->WantReloadUserBuf = false;
         InputTextReconcileUndoState(state, state->TextA.Data, state->TextLen, buf, new_len);
         InputTextReconcileUndoState(state, state->TextA.Data, state->TextLen, buf, new_len);
         state->TextA.resize(buf_size + 1); // we use +1 to make sure that .Data is always pointing to at least an empty string.
         state->TextA.resize(buf_size + 1); // we use +1 to make sure that .Data is always pointing to at least an empty string.
@@ -4540,6 +4542,7 @@ bool ImGui::InputTextEx(const char* label, const char* hint, char* buf, int buf_
         // Take a copy of the initial buffer value.
         // Take a copy of the initial buffer value.
         // From the moment we focused we are normally ignoring the content of 'buf' (unless we are in read-only mode)
         // From the moment we focused we are normally ignoring the content of 'buf' (unless we are in read-only mode)
         const int buf_len = (int)strlen(buf);
         const int buf_len = (int)strlen(buf);
+        IM_ASSERT(buf_len + 1 <= buf_size && "Is your input buffer properly zero-terminated?");
         state->TextToRevertTo.resize(buf_len + 1);    // UTF-8. we use +1 to make sure that .Data is always pointing to at least an empty string.
         state->TextToRevertTo.resize(buf_len + 1);    // UTF-8. we use +1 to make sure that .Data is always pointing to at least an empty string.
         memcpy(state->TextToRevertTo.Data, buf, buf_len + 1);
         memcpy(state->TextToRevertTo.Data, buf, buf_len + 1);
 
 
@@ -4551,7 +4554,7 @@ bool ImGui::InputTextEx(const char* label, const char* hint, char* buf, int buf_
 
 
         // Start edition
         // Start edition
         state->ID = id;
         state->ID = id;
-        state->TextLen = (int)strlen(buf);
+        state->TextLen = buf_len;
         if (!is_readonly)
         if (!is_readonly)
         {
         {
             state->TextA.resize(buf_size + 1); // we use +1 to make sure that .Data is always pointing to at least an empty string.
             state->TextA.resize(buf_size + 1); // we use +1 to make sure that .Data is always pointing to at least an empty string.