diff --git a/src/mcp/mcp.c b/src/mcp/mcp.c index d6c7bd4686..ee4897e5b4 100644 --- a/src/mcp/mcp.c +++ b/src/mcp/mcp.c @@ -1584,8 +1584,19 @@ int cbm_mcp_get_int_arg(const char *args_json, const char *key, int default_val) yyjson_val *root = yyjson_doc_get_root(doc); yyjson_val *val = yyjson_obj_get(root, key); int result = default_val; - if (val && yyjson_is_int(val)) { - result = yyjson_get_int(val); + /* yyjson_get_int truncates 64-bit integers to int (2^32 + 1 became 1); + * read the full width and treat anything outside int range like a + * non-integer, i.e. fall back to the caller's default. */ + if (val && yyjson_is_sint(val)) { + int64_t parsed = yyjson_get_sint(val); + if (parsed >= INT_MIN && parsed <= INT_MAX) { + result = (int)parsed; + } + } else if (val && yyjson_is_uint(val)) { + uint64_t parsed = yyjson_get_uint(val); + if (parsed <= (uint64_t)INT_MAX) { + result = (int)parsed; + } } yyjson_doc_free(doc); return result; diff --git a/tests/test_mcp.c b/tests/test_mcp.c index ffa9ea3a3b..027ab0c50f 100644 --- a/tests/test_mcp.c +++ b/tests/test_mcp.c @@ -1771,6 +1771,23 @@ TEST(mcp_get_int_arg) { ASSERT_EQ(val, 5); val = cbm_mcp_get_int_arg(args, "missing", 42); ASSERT_EQ(val, 42); + /* Out-of-int-range integers return the default instead of truncating: + * 2^32 + 1 used to read back as 1 through yyjson_get_int's int cast. */ + val = cbm_mcp_get_int_arg("{\"limit\":4294967297}", "limit", 17); + ASSERT_EQ(val, 17); + val = cbm_mcp_get_int_arg("{\"limit\":-4294967297}", "limit", 19); + ASSERT_EQ(val, 19); + val = cbm_mcp_get_int_arg("{\"limit\":2147483648}", "limit", 23); + ASSERT_EQ(val, 23); + val = cbm_mcp_get_int_arg("{\"limit\":-9223372036854775808}", "limit", 29); + ASSERT_EQ(val, 29); + /* Boundary values and a negative in-range value still pass through. */ + val = cbm_mcp_get_int_arg("{\"limit\":2147483647}", "limit", 0); + ASSERT_EQ(val, 2147483647); + val = cbm_mcp_get_int_arg("{\"limit\":-2147483648}", "limit", 0); + ASSERT_EQ(val, -2147483648); + val = cbm_mcp_get_int_arg("{\"limit\":-7}", "limit", 0); + ASSERT_EQ(val, -7); PASS(); }