1
0
mirror of https://github.com/opencv/opencv.git synced 2026-07-29 15:23:05 +04:00

core: FileStorage reads integers above INT_MAX into float/double without truncation

FileNode::operator double() and operator float() read an INT node via readInt()
(32-bit), truncating values above INT_MAX -- e.g. an integer 6662329666 from an
externally-produced json/yaml/xml is read back as -1927604926. The node stores
the value as int64 (operator int64_t() already reads it correctly via readLong),
so use readLong() for the floating-point conversions too. Values that fit in
int32 are unchanged (sign-extended); larger ones are now correct.

Reader side of #29363 (the writer side was #29364).
This commit is contained in:
Tonu Samuel
2026-06-23 11:15:11 +03:00
parent 6f29af625b
commit dceead809e
2 changed files with 20 additions and 2 deletions
+2 -2
View File
@@ -2376,7 +2376,7 @@ FileNode::operator float() const
if( type == INT )
{
return (float)readInt(p);
return (float)readLong(p);
}
else if( type == REAL )
{
@@ -2397,7 +2397,7 @@ FileNode::operator double() const
if( type == INT )
{
return (double)readInt(p);
return (double)readLong(p);
}
else if( type == REAL )
{
+18
View File
@@ -2099,6 +2099,24 @@ TEST(Core_InputOutput, FileStorage_int64_26829)
}
}
TEST(Core_InputOutput, FileStorage_read_bigint_as_real_29363)
{
// An integer above INT_MAX (e.g. from externally-produced json/yaml/xml) must
// convert to float/double without truncating to int32. Regression for #29363.
String content =
"%YAML:1.0\n"
"a: 6662329666\n" // ~6.6e9, exact in double
"b: -9876543210\n"
"c: 4294967296\n"; // 2^32, exact in double and float
FileStorage fs(content, FileStorage::READ | FileStorage::MEMORY);
EXPECT_EQ(6662329666.0, (double)fs["a"]);
EXPECT_EQ(-9876543210.0, (double)fs["b"]);
EXPECT_EQ(4294967296.0, (double)fs["c"]);
EXPECT_EQ(4294967296.0f, (float)fs["c"]);
EXPECT_EQ((int64_t)6662329666LL, (int64_t)fs["a"]); // int64 path unchanged
}
template <typename T>
T fsWriteRead(const T& expectedValue, const char* ext)
{