Skip to content

[Bug]: Text/TextColored string-only overloads still parse content as printf format — crashes (SIGSEGV) on unmatched %s #130

Description

@tomast1337

Pre-submission Checklist

  • I have read the FAQ Wiki
  • I have searched existing issues and this is not a duplicate
  • I am using the latest version of Hexa.NET.ImGui

Hexa.NET.ImGui Version

2.2.9

Bug Description

Text/TextColored/TextDisabled overloads that take a plain string (no format args — e.g. ImGui.TextColored(Vector4 col, string fmt)) still forward that string into native cimgui's variadic Text(fmt, ...) / TextColoredV, which calls libc's vsnprintf(buf, size, fmt, args) treating it as a printf format string.

From C#, calling ImGui.TextColored(color, someString) looks completely safe — there's no vararg syntax at the call site, nothing signals the string is still parsed as a format string underneath. But if someString contains a recognized conversion specifier with no matching argument (most plausibly %s, e.g. from an unsubstituted i18n/translation placeholder, a log message, or any user/dynamic content), vsnprintf tries to read a vararg that was never supplied and dereferences whatever garbage it finds on the exhausted va_list. On glibc (Linux) this segfaults the whole process — no exception, no managed stack trace, just a native SIGSEGV.

This is a binding-level footgun: the C# API surface implies safety that the native contract doesn't provide. Confirmed the crash is specific to the format-parsing path — ImGui.TextUnformatted (Dear ImGui's actual non-format-string API) with the exact same string does not crash.

Steps to Reproduce

Minimal standalone repro (no other dependencies, exact package versions below): https://github.com/tomast1337/betasharp-imgui-percent-crash-repro

  1. Clone the repo, dotnet run --configuration Release -- unsafe
  2. Process crashes with SIGSEGV (exit code 139)
  3. dotnet run --configuration Release -- safe runs the identical string through ImGui.TextUnformatted instead — survives cleanly

Expected Behavior

Passing a plain, non-format C# string to Text/TextColored/TextDisabled should never crash, regardless of its content — same guarantee ImGui.NET's equivalent string-only overloads provide (worth checking how they avoid this, e.g. forwarding as "%s", text or calling TextUnformatted internally).

Code Sample

// Crashes (SIGSEGV) — string-only overload, no format args at the call site,
// but the native side still parses it as a printf format string.
ImGui.TextColored(new Vector4(1f, 1f, 1f, 1f), "Player: %s just joined the game");

// Same string, survives — the actual non-format-string API.
ImGui.TextUnformatted("Player: %s just joined the game");

Platform

Linux

.NET Version

net10.0

Additional Context

Confirmed via a real coredump (coredumpctl gdb) that the crashing thread's native stack is:

$ coredumpctl gdb 848542
           PID: 848542 (repro)
           UID: 1000 (tomast1337)
           GID: 1000 (tomast1337)
        Signal: 11 (SEGV)
     Timestamp: Sun 2026-07-19 15:58:15 -03 (1min 16s ago)
  Command Line: ./repro unsafe
    Executable: /home/tomast1337/Projects/betasharp-imgui-percent-crash-repro/bin/Release/net10.0/repro
 Control Group: /user.slice/user-1000.slice/user@1000.service/kitty-847878-0.scope
          Unit: user@1000.service
     User Unit: kitty-847878-0.scope
         Slice: user-1000.slice
     Owner UID: 1000 (tomast1337)
       Boot ID: 47834779441c4d3bb85beaf6ff6f9e31
    Machine ID: 9de1746df06040c8b98032f6f872a3a5
      Hostname: archlinux
       Storage: /var/lib/systemd/coredump/core.repro.1000.47834779441c4d3bb85beaf6ff6f9e31.848542.1784487495000000.zst (present)
  Size on Disk: 7.5M
       Message: Process 848542 (repro) of user 1000 dumped core.
                
                Stack trace of thread 848542:
                #0  0x00007f8c11174d5d n/a (libc.so.6 + 0x174d5d)
                #1  0x00007f8c11067108 n/a (libc.so.6 + 0x67108)
                #2  0x00007f8c1108c39a __vsnprintf (libc.so.6 + 0x8c39a)
                -- this is ImFormatStringV
                #3  0x00007f73254a4330 _Z15ImFormatStringVPcmPKcP13__va_list_tag (cimgui.so + 0xa4330)
                --- ImFormatStringToTempBufferV
                #4  0x00007f73254a4691 _Z27ImFormatStringToTempBufferVPPKcS1_S0_P13__va_list_tag (cimgui.so + 0xa4691)
                --  ImGui::TextV
                #5  0x00007f73255788ad _ZN5ImGui5TextVEPKcP13__va_list_tag (cimgui.so + 0x1788ad)
                --  ImGui::TextColoredV
                #6  0x00007f73255789f0 _ZN5ImGui12TextColoredVERK6ImVec4PKcP13__va_list_tag (cimgui.so + 0x1789f0)
                #7  0x00007f7325486908 igTextColored (cimgui.so + 0x86908)
                #8  0x00007f7325486967 igTextColored0 (cimgui.so + 0x86967)
                #9  0x00007f8b927c25b0 n/a (n/a + 0x0)
                #10 0x00007f8b927c24bf n/a (n/a + 0x0)
                #11 0x00007f8b927c1228 n/a (n/a + 0x0)
                #12 0x00007f8b927c06bb n/a (n/a + 0x0)
                #13 0x00007f8b927c00ff n/a (n/a + 0x0)
                #14 0x00007f8b927bfdaa n/a (n/a + 0x0)
                #15 0x00007f8b927bfd04 n/a (n/a + 0x0)
                #16 0x00007f8b927a33a9 n/a (n/a + 0x0)
                #17 0x00007f8b92781c6b n/a (n/a + 0x0)
                #18 0x00007f8c10cd40cc n/a (libcoreclr.so + 0x4d40cc)
                #19 0x00007f8c10b1d533 n/a (libcoreclr.so + 0x31d533)
                #20 0x00007f8c109f79d2 n/a (libcoreclr.so + 0x1f79d2)
                #21 0x00007f8c109f7e89 n/a (libcoreclr.so + 0x1f7e89)
                #22 0x00007f8c10a22811 n/a (libcoreclr.so + 0x222811)
                #23 0x00007f8c10875f4f coreclr_execute_assembly (libcoreclr.so + 0x75f4f)
                #24 0x00007f8c1129bba7 n/a (libhostpolicy.so + 0x24ba7)
                #25 0x00007f8c1129bf84 n/a (libhostpolicy.so + 0x24f84)
                #26 0x00007f8c1129d0c0 corehost_main (libhostpolicy.so + 0x260c0)
                #27 0x00007f8c116ee3be n/a (libhostfxr.so + 0x113be)
                #28 0x00007f8c116ecd89 n/a (libhostfxr.so + 0xfd89)
                #29 0x00007f8c116e72a3 hostfxr_main_startupinfo (libhostfxr.so + 0xa2a3)
                #30 0x0000563adf84470a n/a (repro + 0x370a)
                #31 0x0000563adf844ab2 n/a (repro + 0x3ab2)
                #32 0x00007f8c11027741 n/a (libc.so.6 + 0x27741)
                #33 0x00007f8c11027879 __libc_start_main (libc.so.6 + 0x27879)
                #34 0x0000563adf8431f5 n/a (repro + 0x21f5)

Isolated minimal repro (this issue's exact scenario, in isolation): https://github.com/tomast1337/betasharp-imgui-percent-crash-repro
Real-world occurrence this was found from: https://git.gay/betasharp-official/betasharp/issues/37

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions