mirror of
https://github.com/mcneel/opennurbs.git
synced 2026-03-20 09:29:26 +08:00
Sync changes from upstream repository
This commit is contained in:
@@ -294,8 +294,8 @@ public:
|
||||
|
||||
const ON_wString& ConvertDoubleArrayToString(int count) const
|
||||
{
|
||||
constexpr int maxCount = 16;
|
||||
if ((count == 0) || (count > maxCount))
|
||||
constexpr int maxCount = array_val_max;
|
||||
if ((count < 1) || (count > maxCount))
|
||||
return _string_val;
|
||||
|
||||
constexpr int maxLen = 30;
|
||||
@@ -329,6 +329,8 @@ public:
|
||||
|
||||
mutable ON_Buffer* _buffer = nullptr;
|
||||
mutable ON_wString _string_val;
|
||||
|
||||
static constexpr int array_val_max = 16;
|
||||
union
|
||||
{
|
||||
bool _bool_val;
|
||||
@@ -338,7 +340,7 @@ public:
|
||||
ON_Xform m_xform;
|
||||
time_t _time_val;
|
||||
ON_UUID _uuid_val;
|
||||
double _array_val[16] = { 0 };
|
||||
double _array_val[array_val_max] = { 0 };
|
||||
};
|
||||
|
||||
ON::LengthUnitSystem _units = ON::LengthUnitSystem::None;
|
||||
@@ -559,7 +561,7 @@ bool ON_XMLVariant::operator == (const ON_XMLVariant& v) const
|
||||
return _private->_time_val == v._private->_time_val;
|
||||
|
||||
case Types::Matrix:
|
||||
for (int i = 0; i < 16; i++)
|
||||
for (int i = 0; i < _private->array_val_max; i++)
|
||||
{
|
||||
if (_private->_array_val[i] != v._private->_array_val[i])
|
||||
return false;
|
||||
@@ -975,18 +977,18 @@ ON_Xform ON_XMLVariant::AsXform(void) const
|
||||
switch (_private->_type)
|
||||
{
|
||||
case Types::Matrix:
|
||||
break;
|
||||
return _private->m_xform;
|
||||
|
||||
case Types::String:
|
||||
if (_private->_string_val.IsValidMatrix())
|
||||
StringToPoint(16); //////////////////////////////////// Risky
|
||||
break;
|
||||
{
|
||||
StringToPoint(16);
|
||||
return _private->m_xform;
|
||||
}
|
||||
|
||||
default:
|
||||
return ON_Xform::Zero4x4;
|
||||
}
|
||||
|
||||
return _private->m_xform;
|
||||
}
|
||||
|
||||
ON_4fColor ON_XMLVariant::AsColor(void) const
|
||||
@@ -1208,27 +1210,66 @@ ON_XMLVariant::operator ON_Buffer() const
|
||||
|
||||
void ON_XMLVariant::StringToPoint(int numValues) const
|
||||
{
|
||||
if ((numValues < 0) || (numValues > 16))
|
||||
return;
|
||||
// 22nd September 2022 John Croudy, https://mcneel.myjetbrains.com/youtrack/issue/RH-77182
|
||||
// This function crashed on the Mac inside wcstod_l() which must be getting called from the call to
|
||||
// ON_wtof(). The only way that function can fail is if either the input pointers are invalid or the
|
||||
// input string or locale is corrupted. I don't have any control over the locale (I don't even know
|
||||
// how it's being accessed on the Mac), so all I can do is check the input string. It's unlikely that
|
||||
// an incorrectly formatted string (i.e., not a float) would cause a crash, but I can do some simple
|
||||
// validation to try and avoid trouble.
|
||||
|
||||
ON_wString s = _private->_string_val + L",0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,";
|
||||
auto* p = s.Array();
|
||||
bool good = true;
|
||||
|
||||
for (int i = 0; i < numValues; i++)
|
||||
if ((numValues < 0) || (numValues > _private->array_val_max))
|
||||
{
|
||||
while (iswspace(*p))
|
||||
good = false;
|
||||
}
|
||||
else
|
||||
if (_private->_string_val.IsEmpty())
|
||||
{
|
||||
good = false;
|
||||
}
|
||||
|
||||
if (good)
|
||||
{
|
||||
ON_wString s = _private->_string_val + L",0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,";
|
||||
|
||||
auto* p = static_cast<const wchar_t*>(s);
|
||||
for (int i = 0; i < numValues; i++)
|
||||
{
|
||||
// Skip white space. iswspace() returns 0 for the terminator so we can't go off the end of the buffer.
|
||||
while (0 != iswspace(*p))
|
||||
{
|
||||
p++;
|
||||
}
|
||||
|
||||
// Quick and simple sanity check at the start of a float value.
|
||||
if (isdigit(*p) || (*p == '.') || (*p == '+') || (*p == '-'))
|
||||
{
|
||||
_private->_array_val[i] = ON_wtof(p);
|
||||
}
|
||||
|
||||
// Because we've appended a fixed string containing commas, we know the pointer can't go off
|
||||
// the end of the buffer while checking for a comma.
|
||||
while (*p != L',')
|
||||
{
|
||||
p++;
|
||||
}
|
||||
|
||||
// 'p' is now pointing to a comma.
|
||||
ON_ASSERT(*p == L',');
|
||||
|
||||
// After incrementing it, the worst case scenario is that it's pointing to the terminator.
|
||||
p++;
|
||||
}
|
||||
|
||||
_private->_array_val[i] = ON_wtof(p);
|
||||
|
||||
while (*p != L',')
|
||||
}
|
||||
else
|
||||
{
|
||||
// Bad input; clear the result to all zeroes.
|
||||
for (int i = 0; i < _private->array_val_max; i++)
|
||||
{
|
||||
p++;
|
||||
_private->_array_val[i] = 0.0;
|
||||
}
|
||||
|
||||
p++;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user