mirror of
https://github.com/Xahau/xahaud.git
synced 2026-09-27 07:36:52 +00:00
fix: tighten jsontx_exact integer boundary at 2^53
jsontx_exact: change the double boundary check from exclusive to inclusive (d > max -> d >= max, d < -max -> d <= -max). Doubles cannot uniquely represent odd integers at or above 2^53, so values like 2^53+1 silently round to 2^53, corrupting the canonical form. The safe ceiling for round-trip-exact integers is 2^53 - 1. tests: add coverage for the 2^53 boundary (positive and negative sides, and the silent rounding case).
This commit is contained in:
committed by
Richard Holland
parent
4fb88f5f80
commit
e470d8a70b
@@ -247,8 +247,7 @@ jsontx_exact(Json::Value const& v, std::int64_t& out)
|
||||
return false;
|
||||
}
|
||||
double const d = v.asDouble();
|
||||
if (!std::isfinite(d) || d != std::trunc(d) || d < -jsontx_exact_max ||
|
||||
d > jsontx_exact_max)
|
||||
if (!std::isfinite(d) || d != std::trunc(d) || d <= -jsontx_exact_max || d >= jsontx_exact_max)
|
||||
return false;
|
||||
out = static_cast<std::int64_t>(d);
|
||||
return true;
|
||||
|
||||
@@ -635,6 +635,42 @@ public:
|
||||
BEAST_EXPECT(r2.second.size() >= r1.second.size());
|
||||
});
|
||||
|
||||
|
||||
// ---- 2^53 boundary: values at and above 2^53 must be rejected ----
|
||||
// Doubles cannot uniquely represent odd integers >= 2^53, so the
|
||||
// safe boundary for exact integer round-trips is 2^53 - 1.
|
||||
section("exact_at_2exp53_boundary",
|
||||
[&] {
|
||||
// 2^53 - 1 should be accepted (max safe value)
|
||||
Json::Value ok;
|
||||
ok = 9007199254740991;
|
||||
std::int64_t out = 0;
|
||||
BEAST_EXPECT(jsontx_exact(ok, out));
|
||||
BEAST_EXPECT(out == 9007199254740991);
|
||||
|
||||
// 2^53 should be rejected (not uniquely representable)
|
||||
Json::Value bad;
|
||||
bad = 9007199254740992;
|
||||
BEAST_EXPECT(!jsontx_exact(bad, out));
|
||||
|
||||
// 2^53 + 1 rounds down to 2^53 in double representation
|
||||
// and should also be rejected
|
||||
Json::Value bad2;
|
||||
bad2 = 9007199254740993;
|
||||
BEAST_EXPECT(!jsontx_exact(bad2, out));
|
||||
|
||||
// Negative boundary: -2^53 should be rejected
|
||||
Json::Value neg_bad;
|
||||
neg_bad = -9007199254740992;
|
||||
BEAST_EXPECT(!jsontx_exact(neg_bad, out));
|
||||
|
||||
// -2^53 + 1 should be accepted
|
||||
Json::Value neg_ok;
|
||||
neg_ok = -9007199254740991;
|
||||
BEAST_EXPECT(jsontx_exact(neg_ok, out));
|
||||
BEAST_EXPECT(out == -9007199254740991);
|
||||
});
|
||||
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
Reference in New Issue
Block a user