Fix integer comparison bug (#5211)

* Fix integer comparison bug

Signed-off-by: ljccjlljc <939159710@qq.com>

* commit

Signed-off-by: ljccjlljc <939159710@qq.com>

* Remove generated CI artifacts and update amalgamation

Signed-off-by: ljccjlljc <939159710@qq.com>

* Silence cpplint braces warning in comparison macro

Signed-off-by: ljccjlljc <939159710@qq.com>

* Update amalgamation after cpplint fix

Signed-off-by: ljccjlljc <939159710@qq.com>

* Add mixed signed and unsigned comparison regression test

Signed-off-by: ljccjlljc <939159710@qq.com>

* Clarify mixed signed and unsigned comparison handling

Signed-off-by: ljccjlljc <939159710@qq.com>

* Expand mixed signed and unsigned comparison tests

Signed-off-by: ljccjlljc <939159710@qq.com>

---------

Signed-off-by: ljccjlljc <939159710@qq.com>
This commit is contained in:
ljcjclljc
2026-08-12 09:21:19 +02:00
committed by GitHub
parent 21af527e75
commit 6285225fd0
3 changed files with 97 additions and 6 deletions
+13 -3
View File
@@ -3652,6 +3652,12 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec
// note parentheses around operands are necessary; see
// https://github.com/nlohmann/json/issues/1530
// Mixed signed/unsigned integer comparisons check whether the signed value
// is negative before casting. If it is, the comparison is performed with
// the fixed values -1 and 1, which preserves the ordering relationship
// because any negative signed value is smaller than any unsigned value.
// Otherwise, the non-negative signed value is cast to unsigned before the
// comparison to avoid wraparound.
#define JSON_IMPLEMENT_OPERATOR(op, null_result, unordered_result, default_result) \
const auto lhs_type = lhs.type(); \
const auto rhs_type = rhs.type(); \
@@ -3710,12 +3716,16 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec
} \
else if (lhs_type == value_t::number_unsigned && rhs_type == value_t::number_integer) \
{ \
return static_cast<number_integer_t>(lhs.m_data.m_value.number_unsigned) op rhs.m_data.m_value.number_integer; \
return (rhs.m_data.m_value.number_integer < 0) \
? (number_integer_t(1) op number_integer_t(-1)) \
: (lhs.m_data.m_value.number_unsigned op static_cast<number_unsigned_t>(rhs.m_data.m_value.number_integer)); \
} \
else if (lhs_type == value_t::number_integer && rhs_type == value_t::number_unsigned) \
{ \
return lhs.m_data.m_value.number_integer op static_cast<number_integer_t>(rhs.m_data.m_value.number_unsigned); \
} \
return (lhs.m_data.m_value.number_integer < 0) \
? (number_integer_t(-1) op number_integer_t(1)) \
: (static_cast<number_unsigned_t>(lhs.m_data.m_value.number_integer) op rhs.m_data.m_value.number_unsigned); \
} \
else if(compares_unordered(lhs, rhs))\
{\
return (unordered_result);\