Another edge case on the upgrade path.
If you add this test case to MaterialXTest/MaterialXCore/Document.cpp and run with MATERIALX_DYNAMIC_ANALYSIS=ON.
TEST_CASE("Document upgrade swizzle empty value", "[document]")
{
mx::DocumentPtr doc = mx::createDocument();
mx::XmlReadOptions readOptions;
readOptions.upgradeVersion = false;
mx::readFromXmlString(doc,
"<?xml version=\"1.0\"?>"
"<materialx version=\"1.38\">"
" <nodegraph name=\"NG1\">"
" <swizzle name=\"swz1\" type=\"color3\" nodedef=\"ND_swizzle\">"
" <input name=\"in\" type=\"color3\" value=\"\"/>"
" <input name=\"channels\" type=\"string\" value=\"\"/>"
" </swizzle>"
" </nodegraph>"
"</materialx>",
mx::FileSearchPath(), &readOptions);
REQUIRE_NOTHROW(doc->upgradeVersion());
}
/usr/include/c++/11/bits/stl_vector.h:1046:34: runtime error: reference binding to null pointer of type 'struct value_type'
It's specifically on the upgrade path for 1.38-1.39, that converts old swizzle nodes to constant nodes.
The in input has an empty value value="". This means inInput->hasValue(); returns true and we go down path
convertToConstantNode = true; // because inInput exists and has a value attribute
...
if (convertToConstantNode)
{
...
string valueString = inInput ? inInput->getValueString() : "0"; // <-- ""
StringVec origValueTokens = splitString(valueString, ARRAY_VALID_SEPARATORS); // <-- empty vector {}
...
newValueTokens.push_back(origValueTokens[0]); // <-- out of range access here
|
string valueString = inInput ? inInput->getValueString() : "0"; |
|
StringVec origValueTokens = splitString(valueString, ARRAY_VALID_SEPARATORS); |
|
StringVec newValueTokens; |
|
for (size_t i = 0; i < destChannelCount; i++) |
|
{ |
|
if (i < channelString.size()) |
|
{ |
|
if (CHANNEL_INDEX_MAP.count(channelString[i])) |
|
{ |
|
size_t index = CHANNEL_INDEX_MAP.at(channelString[i]); |
|
if (index < origValueTokens.size()) |
|
{ |
|
newValueTokens.push_back(origValueTokens[index]); |
|
continue; |
|
} |
|
} |
|
else if (CHANNEL_CONSTANT_MAP.count(channelString[i])) |
|
{ |
|
newValueTokens.push_back(std::to_string(CHANNEL_CONSTANT_MAP.at(channelString[i]))); |
|
continue; |
|
} |
|
} |
|
// Invalid channel name, or missing channel name: |
|
newValueTokens.push_back(origValueTokens[0]); |
|
} |
Another edge case on the upgrade path.
If you add this test case to
MaterialXTest/MaterialXCore/Document.cppand run withMATERIALX_DYNAMIC_ANALYSIS=ON.It's specifically on the upgrade path for 1.38-1.39, that converts old swizzle nodes to constant nodes.
The
ininput has an empty valuevalue="". This meansinInput->hasValue();returns true and we go down pathMaterialX/source/MaterialXCore/Version.cpp
Lines 1264 to 1288 in 8b4b222