Skip to content

fix(ini): Support plus sign character prefix in INI integer parse#2576

Open
xezon wants to merge 3 commits intoTheSuperHackers:mainfrom
xezon:xezon/fix-ini-scanint
Open

fix(ini): Support plus sign character prefix in INI integer parse#2576
xezon wants to merge 3 commits intoTheSuperHackers:mainfrom
xezon:xezon/fix-ini-scanint

Conversation

@xezon
Copy link
Copy Markdown

@xezon xezon commented Apr 11, 2026

Alternative fix to #2548

Omits empty test because a token is implicitly not empty.

This change was not required for the original INI files.

Tested and worked.

@xezon xezon added Minor Severity: Minor < Major < Critical < Blocker ThisProject The issue was introduced by this project, or this task is specific to this project Fix Is fixing something, but is not user facing Mod Relates to Mods or modding labels Apr 11, 2026
@greptile-apps
Copy link
Copy Markdown

greptile-apps bot commented Apr 11, 2026

Greptile Summary

Adds support for +-prefixed integers (and floats) in the std::from_chars-based INI parser by stripping the leading + before calling from_chars, which mirrors sscanf behaviour. As a secondary fix, the intermediate result type for non-integral template instantiations is corrected from the hard-coded Real to the template parameter Type, making the helper properly generic.

Confidence Score: 5/5

Safe to merge — the change is minimal, correct, and all edge cases are handled appropriately.

Only one file changed with a small, focused fix. Stripping the leading + before std::from_chars correctly mirrors sscanf behaviour, the bare-"+" edge case is safely rejected by from_chars returning std::errc::invalid_argument, and the secondary correction from Real to Type improves template correctness. No P0 or P1 issues found.

No files require special attention.

Important Files Changed

Filename Overview
Core/GameEngine/Source/Common/INI/INI.cpp Strips leading + sign before std::from_chars parsing and corrects the intermediate result type from Real to the template parameter Type; logic is sound and edge cases are all handled correctly or intentionally acknowledged.

Reviews (3): Last reviewed commit: "tweak assert message" | Re-trigger Greptile

std::conditional_t<std::is_integral_v<Type>, Int64, Real> result{};
DEBUG_ASSERTCRASH(!token.empty(), ("token is not expected empty"));

// Unlike sscanf, std::from_chars cannot parse "+"
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Same as #2548, this 'fix' needs a comment on why we want to keep parsing the '+' sign

// TheSuperHackers @info std::from_chars does not support a leading '+' sign. Strip it to match // sscanf and accommodate mod makers who use explicit signed values (e.g. +20 / -20).

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

I do not think this level of detail is required for this comment. The comment already clarifies that from_chars behaves different to sscanf, and this difference is mitigated accordingly.

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Could add to the first post that this change is not required for the default ini files.

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

Ok did that. It is implicitly mentioned by the "Mod" label as well.

{
// TheSuperHackers @info std::from_chars cannot parse "-1" as uint32 so the result needs to be int64 for integers.
std::conditional_t<std::is_integral_v<Type>, Int64, Real> result{};
DEBUG_ASSERTCRASH(!token.empty(), ("token is not expected empty"));
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

nit: "token is not expected to be empty"

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

Fixed

DEBUG_ASSERTCRASH(!token.empty(), ("token is not expected empty"));

// Unlike sscanf, std::from_chars cannot parse "+"
if (token[0] == '+')
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Do we care about "+" for integers? If we only care about "+" for floating point values, we could do something like:

if constexpr (std::floating_point<Type>)
{
	// Unlike sscanf, std::from_chars cannot parse "+"
	if (token[0] == '+')
	{
		token.remove_prefix(1);
	}
}

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

In INI file, integer and float are indistinguishable, so a user could add + to both and not be aware about its underlying type.

@Caball009
Copy link
Copy Markdown

Omits empty test because a token is implicitly not empty.

What's this based on? Did you check all call sites?

@xezon
Copy link
Copy Markdown
Author

xezon commented Apr 12, 2026

What's this based on? Did you check all call sites?

I launched the game and it did not hit the assert condition.

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

Labels

Fix Is fixing something, but is not user facing Minor Severity: Minor < Major < Critical < Blocker Mod Relates to Mods or modding ThisProject The issue was introduced by this project, or this task is specific to this project

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants