From 9ee09c1adbabbfcedb4c0a1f7eee4e7267c6efd4 Mon Sep 17 00:00:00 2001 From: Ramakrishna Prabhu Date: Mon, 18 May 2026 14:02:30 -0500 Subject: [PATCH 1/2] Fix two MAJOR SonarQube bugs: signed/unsigned compare and uninit example var MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit mps_parser.cpp (S6214): fread() returns size_t; bufsize is long. The earlier `mps_parser_expects(bufsize != -1L, ...)` rules out the ftell error sentinel but not other negative values, so `fread(...) == bufsize` is a signed/unsigned comparison. Switch to `std::cmp_equal` (C++20) so the comparison is correct across both signs. milp_mps_example.c (S836, plus a related NULL-deref): `objective_value` was read unconditionally even though it is only assigned when `has_primal_solution` is true — undefined behavior on INFEASIBLE/ITERATION_LIMIT terminations. The same applies to `solution_values[i]` further down: malloc'd inside the if-block but indexed unconditionally (NULL deref). Consolidate both reads inside the `if (has_primal_solution)` block so the example is well-defined for all termination statuses. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.7 (1M context) --- cpp/src/io/mps_parser.cpp | 3 ++- .../lp-qp-milp/examples/milp_mps_example.c | 26 ++++++++++--------- 2 files changed, 16 insertions(+), 13 deletions(-) diff --git a/cpp/src/io/mps_parser.cpp b/cpp/src/io/mps_parser.cpp index 61cb1fa314..0db9324f69 100644 --- a/cpp/src/io/mps_parser.cpp +++ b/cpp/src/io/mps_parser.cpp @@ -19,6 +19,7 @@ #include #include #include +#include #ifdef MPS_PARSER_WITH_BZIP2 #include @@ -634,7 +635,7 @@ std::vector mps_parser_t::file_to_string(const std::string& file std::vector buf(bufsize + 1); rewind(fp.get()); - mps_parser_expects(fread(buf.data(), sizeof(char), bufsize, fp.get()) == bufsize, + mps_parser_expects(std::cmp_equal(fread(buf.data(), sizeof(char), bufsize, fp.get()), bufsize), error_type_t::ValidationError, "Error reading MPS file! Given path: %s", mps_file.c_str()); diff --git a/docs/cuopt/source/cuopt-c/lp-qp-milp/examples/milp_mps_example.c b/docs/cuopt/source/cuopt-c/lp-qp-milp/examples/milp_mps_example.c index c61a29bd95..36e1a1d969 100644 --- a/docs/cuopt/source/cuopt-c/lp-qp-milp/examples/milp_mps_example.c +++ b/docs/cuopt/source/cuopt-c/lp-qp-milp/examples/milp_mps_example.c @@ -119,21 +119,23 @@ cuopt_int_t solve_mps_file(const char* filename) termination_status_to_string(termination_status), termination_status); printf("Solve time: %f seconds\n", time); - printf("Objective value: %f\n", objective_value); - // Get and print solution variables if (has_primal_solution) { - solution_values = (cuopt_float_t*)malloc(num_variables * sizeof(cuopt_float_t)); - status = cuOptGetPrimalSolution(solution, solution_values); - if (status != CUOPT_SUCCESS) { - printf("Error getting solution values: %d\n", status); - goto DONE; - } - } + printf("Objective value: %f\n", objective_value); - printf("\nSolution: \n"); - for (cuopt_int_t i = 0; i < num_variables; i++) { - printf("x%d = %f\n", i + 1, solution_values[i]); + // Get and print solution variables + solution_values = + (cuopt_float_t*)malloc(num_variables * sizeof(cuopt_float_t)); + status = cuOptGetPrimalSolution(solution, solution_values); + if (status != CUOPT_SUCCESS) { + printf("Error getting solution values: %d\n", status); + goto DONE; + } + + printf("\nSolution: \n"); + for (cuopt_int_t i = 0; i < num_variables; i++) { + printf("x%d = %f\n", i + 1, solution_values[i]); + } } DONE: From 4f5ea40e09e43b9d9cf953571cf51b292fd9d6e7 Mon Sep 17 00:00:00 2001 From: Ramakrishna Prabhu Date: Mon, 18 May 2026 14:19:51 -0500 Subject: [PATCH 2/2] Check malloc result before passing solution buffer to cuOpt API MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Mirrors the error-checking pattern used elsewhere in this example. size_t cast on the malloc size avoids signed multiplication overflow. Thanks to CodeRabbit for the catch. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.7 (1M context) --- .../source/cuopt-c/lp-qp-milp/examples/milp_mps_example.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/docs/cuopt/source/cuopt-c/lp-qp-milp/examples/milp_mps_example.c b/docs/cuopt/source/cuopt-c/lp-qp-milp/examples/milp_mps_example.c index 36e1a1d969..82109492a7 100644 --- a/docs/cuopt/source/cuopt-c/lp-qp-milp/examples/milp_mps_example.c +++ b/docs/cuopt/source/cuopt-c/lp-qp-milp/examples/milp_mps_example.c @@ -125,7 +125,12 @@ cuopt_int_t solve_mps_file(const char* filename) // Get and print solution variables solution_values = - (cuopt_float_t*)malloc(num_variables * sizeof(cuopt_float_t)); + (cuopt_float_t*)malloc((size_t)num_variables * sizeof(cuopt_float_t)); + if (solution_values == NULL) { + printf("Error allocating solution buffer\n"); + status = CUOPT_OUT_OF_MEMORY; + goto DONE; + } status = cuOptGetPrimalSolution(solution, solution_values); if (status != CUOPT_SUCCESS) { printf("Error getting solution values: %d\n", status);