fix NULL pointer dereference in AMF XML parser

slic3r/Slic3r#5117
This commit is contained in:
supermerill 2022-01-31 01:48:16 +01:00
parent 1a86054e68
commit 211aaa3d32

View File

@ -124,6 +124,16 @@ struct AMFParserContext
return nullptr; return nullptr;
} }
static const char* get_not_null_attribute(const char** atts, const char* id) {
const char* str = get_attribute(atts, id);
if (str == nullptr) {
char error_buf[1024];
::sprintf(error_buf, "Error, missing tag %s", id);
throw Slic3r::FileIOError(error_buf);
}
return str;
}
enum AMFNodeType { enum AMFNodeType {
NODE_TYPE_INVALID = 0, NODE_TYPE_INVALID = 0,
NODE_TYPE_UNKNOWN, NODE_TYPE_UNKNOWN,
@ -304,7 +314,7 @@ void AMFParserContext::startElement(const char *name, const char **atts)
case 2: case 2:
if (strcmp(name, "metadata") == 0) { if (strcmp(name, "metadata") == 0) {
if (m_path[1] == NODE_TYPE_MATERIAL || m_path[1] == NODE_TYPE_OBJECT) { if (m_path[1] == NODE_TYPE_MATERIAL || m_path[1] == NODE_TYPE_OBJECT) {
m_value[0] = get_attribute(atts, "type"); m_value[0] = get_not_null_attribute(atts, "type");
node_type_new = NODE_TYPE_METADATA; node_type_new = NODE_TYPE_METADATA;
} }
} else if (strcmp(name, "layer_config_ranges") == 0 && m_path[1] == NODE_TYPE_OBJECT) } else if (strcmp(name, "layer_config_ranges") == 0 && m_path[1] == NODE_TYPE_OBJECT)
@ -329,19 +339,19 @@ void AMFParserContext::startElement(const char *name, const char **atts)
else if (m_path[1] == NODE_TYPE_CUSTOM_GCODE) { else if (m_path[1] == NODE_TYPE_CUSTOM_GCODE) {
if (strcmp(name, "code") == 0) { if (strcmp(name, "code") == 0) {
node_type_new = NODE_TYPE_GCODE_PER_HEIGHT; node_type_new = NODE_TYPE_GCODE_PER_HEIGHT;
m_value[0] = get_attribute(atts, "print_z"); m_value[0] = get_not_null_attribute(atts, "print_z");
m_value[1] = get_attribute(atts, "extruder"); m_value[1] = get_not_null_attribute(atts, "extruder");
m_value[2] = get_attribute(atts, "color"); m_value[2] = get_not_null_attribute(atts, "color");
if (get_attribute(atts, "type")) if (get_attribute(atts, "type"))
{ {
m_value[3] = get_attribute(atts, "type"); m_value[3] = get_not_null_attribute(atts, "type");
m_value[4] = get_attribute(atts, "extra"); m_value[4] = get_not_null_attribute(atts, "extra");
} }
else else
{ {
// It means that data was saved in old version (2.2.0 and older) of PrusaSlicer // It means that data was saved in old version (2.2.0 and older) of PrusaSlicer
// read old data ... // read old data ...
std::string gcode = get_attribute(atts, "gcode"); std::string gcode = get_not_null_attribute(atts, "gcode");
// ... and interpret them to the new data // ... and interpret them to the new data
CustomGCode::Type type= gcode == "M600" ? CustomGCode::ColorChange : CustomGCode::Type type= gcode == "M600" ? CustomGCode::ColorChange :
gcode == "M601" ? CustomGCode::PausePrint : gcode == "M601" ? CustomGCode::PausePrint :
@ -353,7 +363,7 @@ void AMFParserContext::startElement(const char *name, const char **atts)
} }
else if (strcmp(name, "mode") == 0) { else if (strcmp(name, "mode") == 0) {
node_type_new = NODE_TYPE_CUSTOM_GCODE_MODE; node_type_new = NODE_TYPE_CUSTOM_GCODE_MODE;
m_value[0] = get_attribute(atts, "value"); m_value[0] = get_not_null_attribute(atts, "value");
} }
} }
break; break;
@ -421,7 +431,7 @@ void AMFParserContext::startElement(const char *name, const char **atts)
node_type_new = NODE_TYPE_TRIANGLE; node_type_new = NODE_TYPE_TRIANGLE;
} }
else if (m_path[3] == NODE_TYPE_RANGE && strcmp(name, "metadata") == 0) { else if (m_path[3] == NODE_TYPE_RANGE && strcmp(name, "metadata") == 0) {
m_value[0] = get_attribute(atts, "type"); m_value[0] = get_not_null_attribute(atts, "type");
node_type_new = NODE_TYPE_METADATA; node_type_new = NODE_TYPE_METADATA;
} }
break; break;