Skip to content

fix overflow when control binding text exceeds 40 chars - #7987

Open
Goober5000 wants to merge 2 commits into
scp-fs2open:masterfrom
Goober5000:fix/control_translation_length
Open

Goober5000 wants to merge 2 commits into
scp-fs2open:masterfrom
Goober5000:fix/control_translation_length

Conversation

@Goober5000

@Goober5000 Goober5000 commented Nov 3, 2026 •

Copy link
Copy Markdown
Contributor

translate_key() built the text for a $token$ in training messages, e.g. "Alt-Shift-Backspace or Joy-0 Hat Forward", in a 40-byte static buffer, and strcpy_s treats an overflow as a fatal error. This can happen without any mod: the example above is exactly 40 characters, so it doesn't fit with the terminator. A mod that translates the Joy-N prefix or other binding text to something longer makes it much easier to hit.

Changes:

  • translate_key() now takes an SCP_string &out and returns bool, instead of returning a pointer into a static buffer. This removes the length limit and also avoids a reentrancy problem: the unbound-key popup can run script hooks that call ba.replaceTokens, which would overwrite (or, with an SCP_string, reallocate) the static buffer while the caller still holds a pointer into it.
  • bound_string in the control config screen is enlarged to 256 bytes. It is fitted to the display width anyway.
  • The buffer sizes passed to force_fit_string in the control config screen are now named constants.
  • The gameplay help binding line is built in an SCP_string for consistency.

Not addressed here: the directive key line in HudGaugeDirectives::render() still copies into a 256-byte buffer for split_str_once(), which will be handled separately.

@Goober5000 Goober5000 added fix A fix for bugs, not-a-bugs, and/or regressions. controls A feature or issue related to input devices or actions controlled/triggered by them labels Nov 3, 2026
@Goober5000
Goober5000 requested a review from z64555 as a code owner November 3, 2026 03:37
@Goober5000 Goober5000 added the ui A feature or issue specific to the menus portion of the user interface label Nov 3, 2026
Comment thread code/controlconfig/controlsconfig.cpp Outdated
static unsigned int Defaults_cycle_pos = 0; // the controls preset that was last selected
static UI_TIMESTAMP bound_timestamp;
static char bound_string[40];
static char bound_string[256];

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Erm, why are we still using a magic number here? Maybe use a constant.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

done

Comment thread code/controlconfig/controlsconfig.cpp Outdated
if (done) {
// done with binding mode, clean up and prepare for display
font::force_fit_string(bound_string, 39, Conflict_wnd_coords[gr_screen.res][CONTROL_W_COORD]);
font::force_fit_string(bound_string, 255, Conflict_wnd_coords[gr_screen.res][CONTROL_W_COORD]);

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Magic number.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

done

@Goober5000
Goober5000 force-pushed the fix/control_translation_length branch from 7e8f8a4 to 50f5c4a Compare November 3, 2026 05:47
@Goober5000
Goober5000 requested a review from z64555 November 3, 2026 05:48

@dustinspace217 dustinspace217 left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The new constants cover z64555's notes, and the SCP_string change fixes the crash: I reproduced it on master with a long Joy-0 translation, and this build gets through the same mission.

One thing to change: translate_key now returns a pointer into a static SCP_string. If a script's dialog hook calls ba.replaceTokens while the unbound-key popup is open, the inner call can reallocate that string and free the memory the outer pointer still uses before buf += ptr. Returning SCP_string by value, or copying ptr into a local before the popup, fixes it.

Two smaller notes, fine to leave for later: the directive key line still copies into a 256-byte buffer (missiontraining.cpp:299), and the controls screen still copies into 256-byte buffers before force_fit_string. Both only matter for very long translations. Also, this isn't translation-only: by my count from the code, "Alt-Shift-Backspace or Joy-0 Hat Forward" is exactly 40 characters, so a player who binds that can hit the old crash with no mod at all.

@Goober5000 Goober5000 changed the title fix overflow when translated control text exceeds 40 chars fix overflow when control binding text exceeds 40 chars Nov 4, 2026
Goober5000 and others added 2 commits November 3, 2026 23:38
A mod that translates the "Joy-N " prefix (or other binding text) to
something longer could overflow the 40-byte buffer in translate_key(),
which strcpy_s treats as a fatal error.  Build the text in an SCP_string
instead.  Also enlarge bound_string in the control config screen (it is
width-fitted for display anyway) and convert the gameplay help binding
line to SCP_string for consistency.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@Goober5000
Goober5000 force-pushed the fix/control_translation_length branch from 50f5c4a to 5e59e82 Compare November 4, 2026 04:38
@Goober5000

Copy link
Copy Markdown
Contributor Author

@dustinspace217 updated again

@dustinspace217 dustinspace217 left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for the update. Given the scope of the change I didn't re-run anything, but the change looks good!

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

Labels

controls A feature or issue related to input devices or actions controlled/triggered by them fix A fix for bugs, not-a-bugs, and/or regressions. ui A feature or issue specific to the menus portion of the user interface

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants