mirror of
https://github.com/nlohmann/json.git
synced 2026-08-15 05:33:17 +00:00
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:
@@ -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);\
|
||||
|
||||
Reference in New Issue
Block a user