fix(console): don't coerce quoted or malformed numeric args to JSON numbers
BuildConsoleRpcCall pushed any bare token that "looked numeric" as a JSON
number, and lost the tokenizer's quoting decision — so a genuinely-string
argument that happened to be all digits (e.g. a label) was sent with the wrong
type. std::stoll also silently truncated "1e999" to 1 (stops at the first
non-digit) and std::stod could yield inf/subnormal.
- ParseConsoleCommandArgsTagged returns {text, quoted}; quoted tokens are sent
verbatim as JSON strings, never coerced. (ParseConsoleCommandArgs kept as a
text-only wrapper so existing callers/tests are unchanged.)
- Bare tokens become a number only when the WHOLE token parses to a finite
int/double; otherwise they're sent as a string.
Adds test coverage for quoted-numeric-string, bare-number, 1e999, and 123abc.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -3200,6 +3200,23 @@ void testConsoleInputModel()
|
||||
EXPECT_TRUE(call.params[0].get<bool>());
|
||||
EXPECT_EQ(call.params[1].get<long long>(), 4LL);
|
||||
|
||||
// Quoted numeric-looking args must stay strings (not coerced to numbers).
|
||||
auto qcall = dragonx::ui::BuildConsoleRpcCall("setaccount \"123\" \"456.7\"");
|
||||
EXPECT_TRUE(qcall.valid);
|
||||
EXPECT_EQ(qcall.params.size(), static_cast<size_t>(2));
|
||||
EXPECT_TRUE(qcall.params[0].is_string());
|
||||
EXPECT_EQ(qcall.params[0].get<std::string>(), std::string("123"));
|
||||
EXPECT_TRUE(qcall.params[1].is_string());
|
||||
// Bare finite numbers become numbers; non-finite / non-whole-token tokens fall back to strings
|
||||
// (no std::stoll truncation of "1e999" to 1, no inf).
|
||||
auto ncall = dragonx::ui::BuildConsoleRpcCall("foo 42 3.5 1e999 123abc");
|
||||
EXPECT_TRUE(ncall.params[0].is_number_integer());
|
||||
EXPECT_EQ(ncall.params[0].get<long long>(), 42LL);
|
||||
EXPECT_TRUE(ncall.params[1].is_number_float());
|
||||
EXPECT_TRUE(ncall.params[2].is_string());
|
||||
EXPECT_EQ(ncall.params[2].get<std::string>(), std::string("1e999"));
|
||||
EXPECT_TRUE(ncall.params[3].is_string());
|
||||
|
||||
auto resultLines = dragonx::ui::FormatConsoleRpcResultLines("{\n \"balance\": 12,\n \"ok\": true\n}", false);
|
||||
EXPECT_EQ(resultLines.size(), static_cast<size_t>(4));
|
||||
EXPECT_EQ(resultLines[0].role, dragonx::ui::ConsoleResultLineRole::JsonBrace);
|
||||
|
||||
Reference in New Issue
Block a user