Просмотр исходного кода

TiXmlNode::ToElement() can return NULL, for example in the case of an XML c
omment. Never call ToElement without first sanitizing for NULL.

mcc 13 лет назад
Родитель
Сommit
759f0a54e5

+ 5 - 2
Core/Contents/Source/PolyConfig.cpp

@@ -48,9 +48,12 @@ void Config::loadConfig(const String& configNamespace, const String& fileName) {
 	TiXmlNode *pChild;
 	ConfigEntry *entry;
 	for(pChild = rootElement->FirstChild(); pChild != 0; pChild = pChild->NextSibling()) {
+		TiXmlElement *pChildElement = pChild->ToElement();
+		if (!pChildElement) continue; // Skip comment nodes
+		
 		entry = getEntry(configNamespace, pChild->Value());
-		entry->stringVal = pChild->ToElement()->GetText();		
-		entry->numVal = atof(pChild->ToElement()->GetText());
+		entry->stringVal = pChildElement->GetText();		
+		entry->numVal = atof(pChildElement->GetText());
 		entry->isString = true;
 		entry->configNamespace = configNamespace;
 	}

+ 14 - 7
Core/Contents/Source/PolyGLSLShaderModule.cpp

@@ -116,10 +116,15 @@ Shader *GLSLShaderModule::createShader(TiXmlNode *node) {
 	GLSLProgram *vp = NULL;
 	GLSLProgram *fp = NULL;
 	GLSLShader *retShader = NULL;
+	TiXmlElement *nodeElement = node->ToElement();
+	if (!nodeElement) return NULL; // Skip comment nodes
 	
 	for (pChild = node->FirstChild(); pChild != 0; pChild = pChild->NextSibling()) {
+		TiXmlElement *pChildElement = pChild->ToElement();
+		if (!pChildElement) continue; // Skip comment nodes
+		
 		if(strcmp(pChild->Value(), "vp") == 0) {
-			vp = (GLSLProgram*)CoreServices::getInstance()->getResourceManager()->getResource(Resource::RESOURCE_PROGRAM, String(pChild->ToElement()->Attribute("source")));
+			vp = (GLSLProgram*)CoreServices::getInstance()->getResourceManager()->getResource(Resource::RESOURCE_PROGRAM, String(pChildElement->Attribute("source")));
 			if(vp) {
 				for (pChild2 = pChild->FirstChild(); pChild2 != 0; pChild2 = pChild2->NextSibling()) {
 					if(strcmp(pChild2->Value(), "params") == 0) {
@@ -133,7 +138,7 @@ Shader *GLSLShaderModule::createShader(TiXmlNode *node) {
 			}
 		}
 		if(strcmp(pChild->Value(), "fp") == 0) {
-			fp = (GLSLProgram*)CoreServices::getInstance()->getResourceManager()->getResource(Resource::RESOURCE_PROGRAM, String(pChild->ToElement()->Attribute("source")));
+			fp = (GLSLProgram*)CoreServices::getInstance()->getResourceManager()->getResource(Resource::RESOURCE_PROGRAM, String(pChildElement->Attribute("source")));
 			if(fp) {
 				for (pChild2 = pChild->FirstChild(); pChild2 != 0; pChild2 = pChild2->NextSibling()) {
 					if(strcmp(pChild2->Value(), "params") == 0) {
@@ -150,7 +155,7 @@ Shader *GLSLShaderModule::createShader(TiXmlNode *node) {
 	}
 	if(vp != NULL && fp != NULL) {
 		GLSLShader *cgShader = new GLSLShader(vp,fp);
-		cgShader->setName(String(node->ToElement()->Attribute("name")));
+		cgShader->setName(String(nodeElement->Attribute("name")));
 		retShader = cgShader;
 		shaders.push_back((Shader*)cgShader);
 	}
@@ -710,10 +715,12 @@ void GLSLShaderModule::addParamToProgram(GLSLProgram *program,TiXmlNode *node) {
 		int autoID = 0;
 		int paramType = GLSLProgramParam::PARAM_UNKNOWN;
 		void *defaultData = NULL;
+		TiXmlElement *nodeElement = node->ToElement();
+		if (!nodeElement) return; // Skip comment nodes
 		
-		if(strcmp(node->ToElement()->Attribute("type"), "auto") == 0) {
+		if(strcmp(nodeElement->Attribute("type"), "auto") == 0) {
 			isAuto = true;
-			String pid = node->ToElement()->Attribute("id");
+			String pid = nodeElement->Attribute("id");
 			if(pid == "POLY_MODELVIEWPROJ_MATRIX")
 				autoID = GLSLProgramParam::POLY_MODELVIEWPROJ_MATRIX;
 			else if(pid == "POLY_AREA_LIGHT_POSITION_0")
@@ -800,10 +807,10 @@ void GLSLShaderModule::addParamToProgram(GLSLProgram *program,TiXmlNode *node) {
 			else
 				isAuto = false;
 		} else {
-			defaultData = GLSLProgramParam::createParamData(&paramType, node->ToElement()->Attribute("type"), node->ToElement()->Attribute("default"));
+			defaultData = GLSLProgramParam::createParamData(&paramType, nodeElement->Attribute("type"), nodeElement->Attribute("default"));
 		}
 		
-		program->addParam(node->ToElement()->Attribute("name"), isAuto, autoID, paramType, defaultData);
+		program->addParam(nodeElement->Attribute("name"), isAuto, autoID, paramType, defaultData);
 }
 
 void GLSLShaderModule::reloadPrograms() {

+ 71 - 40
Core/Contents/Source/PolyMaterialManager.cpp

@@ -155,11 +155,13 @@ void MaterialManager::loadMaterialsFromFile(String fileName) {
 }
 
 Shader *MaterialManager::createShaderFromXMLNode(TiXmlNode *node) {
-	Shader *retShader = NULL;
+	TiXmlElement *nodeElement = node->ToElement();
+	if (!nodeElement) return NULL; // Skip comment nodes
 	
+	Shader *retShader = NULL;
 	
-	if(node->ToElement()->Attribute("type")) {
-		String shaderType = node->ToElement()->Attribute("type");
+	if(nodeElement->Attribute("type")) {
+		String shaderType = nodeElement->Attribute("type");
 //		Logger::log("Attempting to create %s shader\n", shaderType.c_str());
 		for(int m=0; m < shaderModules.size(); m++) {
 			PolycodeShaderModule *shaderModule = shaderModules[m];
@@ -172,11 +174,11 @@ Shader *MaterialManager::createShaderFromXMLNode(TiXmlNode *node) {
 	int numAreaLights = 0;
 	int numSpotLights = 0;
 		
-	if(node->ToElement()->Attribute("numAreaLights")) {
-		numAreaLights = atoi(node->ToElement()->Attribute("numAreaLights"));
+	if(nodeElement->Attribute("numAreaLights")) {
+		numAreaLights = atoi(nodeElement->Attribute("numAreaLights"));
 	}
-	if(node->ToElement()->Attribute("numSpotLights")) {
-		numSpotLights = atoi(node->ToElement()->Attribute("numSpotLights"));
+	if(nodeElement->Attribute("numSpotLights")) {
+		numSpotLights = atoi(nodeElement->Attribute("numSpotLights"));
 	}
 	
 	if(retShader) {
@@ -188,15 +190,18 @@ Shader *MaterialManager::createShaderFromXMLNode(TiXmlNode *node) {
 }
 
 Shader *MaterialManager::setShaderFromXMLNode(TiXmlNode *node) {
+	TiXmlElement *nodeElement = node->ToElement();
+	if (!nodeElement) return NULL; // Skip comment nodes
+	
 	Shader *retShader = NULL;
-	if(node->ToElement()->Attribute("type")) {
-		String shaderType = node->ToElement()->Attribute("type");
+	if(nodeElement->Attribute("type")) {
+		String shaderType = nodeElement->Attribute("type");
 		if(shaderType == "fixed") {
 			FixedShader *fShader =  new FixedShader();		
 			retShader = fShader;
 		}
 	} else {
-		retShader = (Shader*)CoreServices::getInstance()->getResourceManager()->getResource(Resource::RESOURCE_SHADER, node->ToElement()->Attribute("name"));
+		retShader = (Shader*)CoreServices::getInstance()->getResourceManager()->getResource(Resource::RESOURCE_SHADER, nodeElement->Attribute("name"));
 	}
 	return retShader;
 }
@@ -213,10 +218,13 @@ Shader *MaterialManager::setShaderFromXMLNode(TiXmlNode *node) {
 
 
 Cubemap *MaterialManager::cubemapFromXMLNode(TiXmlNode *node) {
-	Cubemap *newCubemap;
+	TiXmlElement *nodeElement = node->ToElement();
+	if (!nodeElement) return NULL; // Skip comment nodes
+	
+	Cubemap *newCubemap = NULL;
 	
-	String name = node->ToElement()->Attribute("name");
-	String mapString = node->ToElement()->GetText();
+	String name = nodeElement->Attribute("name");
+	String mapString = nodeElement->GetText();
 	
 	vector<String> maps = mapString.split(",");	
 	if(maps.size() != 6) {
@@ -237,7 +245,10 @@ Cubemap *MaterialManager::cubemapFromXMLNode(TiXmlNode *node) {
 }
 
 Material *MaterialManager::materialFromXMLNode(TiXmlNode *node) {
-	String mname = node->ToElement()->Attribute("name");
+	TiXmlElement *nodeElement = node->ToElement();
+	if (!nodeElement) return NULL; // Skip comment nodes
+
+	String mname = nodeElement->Attribute("name");
 	TiXmlNode* pChild, *pChild2,*pChild3;
 	Shader *materialShader;
 	ShaderBinding *newShaderBinding;
@@ -249,26 +260,32 @@ Material *MaterialManager::materialFromXMLNode(TiXmlNode *node) {
 	Material *newMaterial = new Material(mname);
 
 	for (pChild3 = node->FirstChild(); pChild3 != 0; pChild3 = pChild3->NextSibling()) {
+		TiXmlElement *pChild3Element = pChild3->ToElement();
+		if (!pChild3Element) continue; // Skip comment nodes
+
 		if(strcmp(pChild3->Value(), "rendertargets") == 0) {
 			
-			if(pChild3->ToElement()->Attribute("type")) {
-				if(strcmp(pChild3->ToElement()->Attribute("type"), "rgba_fp16") == 0) {
+			if(pChild3Element->Attribute("type")) {
+				if(strcmp(pChild3Element->Attribute("type"), "rgba_fp16") == 0) {
 					newMaterial->fp16RenderTargets = true;
 				}			
 			}
 		
 			for (pChild = pChild3->FirstChild(); pChild != 0; pChild = pChild->NextSibling()) {
+				TiXmlElement *pChildElement = pChild->ToElement();
+				if (!pChildElement) continue; // Skip comment nodes
+
 				if(strcmp(pChild->Value(), "rendertarget") == 0) {
 					ShaderRenderTarget *newTarget = new ShaderRenderTarget;
-					newTarget->id = pChild->ToElement()->Attribute("id");
+					newTarget->id = pChildElement->Attribute("id");
 					newTarget->width = CoreServices::getInstance()->getRenderer()->getXRes();
 					newTarget->height = CoreServices::getInstance()->getRenderer()->getYRes();
 					newTarget->sizeMode = ShaderRenderTarget::SIZE_MODE_PIXELS;					
-					if(pChild->ToElement()->Attribute("width") && pChild->ToElement()->Attribute("height")) {
-						newTarget->width = atof(pChild->ToElement()->Attribute("width"));
-						newTarget->height = atof(pChild->ToElement()->Attribute("height"));	
-						if(pChild->ToElement()->Attribute("sizeMode")) {
-							if(strcmp(pChild->ToElement()->Attribute("sizeMode"), "normalized") == 0) {
+					if(pChildElement->Attribute("width") && pChildElement->Attribute("height")) {
+						newTarget->width = atof(pChildElement->Attribute("width"));
+						newTarget->height = atof(pChildElement->Attribute("height"));	
+						if(pChildElement->Attribute("sizeMode")) {
+							if(strcmp(pChildElement->Attribute("sizeMode"), "normalized") == 0) {
 								if(newTarget->width > 1.0f)
 									newTarget->width = 1.0f;
 								if(newTarget->height > 1.0f)
@@ -293,18 +310,20 @@ Material *MaterialManager::materialFromXMLNode(TiXmlNode *node) {
 	}
 	
 	for (pChild3 = node->FirstChild(); pChild3 != 0; pChild3 = pChild3->NextSibling()) {
-	
+		TiXmlElement *pChild3Element = pChild3->ToElement();
+		if (!pChild3Element) continue; // Skip comment nodes
+
 		if(strcmp(pChild3->Value(), "specularValue") == 0) {
-			newMaterial->specularValue = atof(pChild3->ToElement()->GetText());
+			newMaterial->specularValue = atof(pChild3Element->GetText());
 		}
 
 		if(strcmp(pChild3->Value(), "specularStrength") == 0) {
-			newMaterial->specularStrength = atof(pChild3->ToElement()->GetText());
+			newMaterial->specularStrength = atof(pChild3Element->GetText());
 		}
 
 
 		if(strcmp(pChild3->Value(), "specularColor") == 0) {		
-			String value = pChild3->ToElement()->GetText();
+			String value = pChild3Element->GetText();
 			vector<String> values = value.split(" ");
 			if(values.size() == 4) {
 				newMaterial->specularColor.setColor(atof(values[0].c_str()), atof(values[1].c_str()), atof(values[2].c_str()),atof(values[3].c_str()));
@@ -314,7 +333,7 @@ Material *MaterialManager::materialFromXMLNode(TiXmlNode *node) {
 		}
 
 		if(strcmp(pChild3->Value(), "diffuseColor") == 0) {
-			String value = pChild3->ToElement()->GetText();
+			String value = pChild3Element->GetText();
 			vector<String> values = value.split(" ");
 			if(values.size() == 4) {
 				newMaterial->diffuseColor.setColor(atof(values[0].c_str()), atof(values[1].c_str()), atof(values[2].c_str()),atof(values[3].c_str()));
@@ -331,28 +350,37 @@ Material *MaterialManager::materialFromXMLNode(TiXmlNode *node) {
 				materialShaders.push_back(materialShader);
 				newShaderBindings.push_back(newShaderBinding);
 				for (pChild = pChild3->FirstChild(); pChild != 0; pChild = pChild->NextSibling()) {
+					TiXmlElement *pChildElement = pChild->ToElement();
+					if (!pChildElement) continue; // Skip comment nodes
+
 					if(strcmp(pChild->Value(), "params") == 0) {
 						for (pChild2 = pChild->FirstChild(); pChild2 != 0; pChild2 = pChild2->NextSibling()) {
+							TiXmlElement *pChild2Element = pChild2->ToElement();
+							if (!pChild2Element) continue; // Skip comment nodes
+
 							if(strcmp(pChild2->Value(), "param") == 0){
-								String pname =  pChild2->ToElement()->Attribute("name");
-								String ptype =  pChild2->ToElement()->Attribute("type");
-								String pvalue =  pChild2->ToElement()->Attribute("value");
+								String pname =  pChild2Element->Attribute("name");
+								String ptype =  pChild2Element->Attribute("type");
+								String pvalue =  pChild2Element->Attribute("value");
 								newShaderBinding->addParam(ptype, pname, pvalue);
 							}						
 						}
 					}
 					if(strcmp(pChild->Value(), "targettextures") == 0) {
 						for (pChild2 = pChild->FirstChild(); pChild2 != 0; pChild2 = pChild2->NextSibling()) {
+							TiXmlElement *pChild2Element = pChild2->ToElement();
+							if (!pChild2Element) continue; // Skip comment nodes
+
 							if(strcmp(pChild2->Value(), "targettexture") == 0){
 							
 								RenderTargetBinding* newBinding = new RenderTargetBinding;
-								newBinding->id = pChild2->ToElement()->Attribute("id");
+								newBinding->id = pChild2Element->Attribute("id");
 								
 								newBinding->name = "";
-								if(pChild2->ToElement()->Attribute("name")) {
-									newBinding->name = pChild2->ToElement()->Attribute("name");
+								if(pChild2Element->Attribute("name")) {
+									newBinding->name = pChild2Element->Attribute("name");
 								}
-								String mode = pChild2->ToElement()->Attribute("mode");
+								String mode = pChild2Element->Attribute("mode");
 								if(strcmp(mode.c_str(), "in") == 0) {
 									newBinding->mode = RenderTargetBinding::MODE_IN;
 								} else {
@@ -380,20 +408,23 @@ Material *MaterialManager::materialFromXMLNode(TiXmlNode *node) {
 					}					
 					if(strcmp(pChild->Value(), "textures") == 0) {
 						for (pChild2 = pChild->FirstChild(); pChild2 != 0; pChild2 = pChild2->NextSibling()) {
+							TiXmlElement *pChild2Element = pChild2->ToElement();
+							if (!pChild2Element) continue; // Skip comment nodes
+
 							if(strcmp(pChild2->Value(), "texture") == 0){
 								String tname = "";
-								if(pChild2->ToElement()->Attribute("name")) {
-									tname =  pChild2->ToElement()->Attribute("name");
+								if(pChild2Element->Attribute("name")) {
+									tname =  pChild2Element->Attribute("name");
 								}
-								newShaderBinding->addTexture(tname, (Texture*)CoreServices::getInstance()->getResourceManager()->getResource(Resource::RESOURCE_TEXTURE, pChild2->ToElement()->GetText()));
+								newShaderBinding->addTexture(tname, (Texture*)CoreServices::getInstance()->getResourceManager()->getResource(Resource::RESOURCE_TEXTURE, pChild2Element->GetText()));
 							}
 							
 							if(strcmp(pChild2->Value(), "cubemap") == 0){
 								String tname = "";
-								if(pChild2->ToElement()->Attribute("name")) {
-									tname =  pChild2->ToElement()->Attribute("name");
+								if(pChild2Element->Attribute("name")) {
+									tname =  pChild2Element->Attribute("name");
 								}
-								newShaderBinding->addCubemap(tname, (Cubemap*)CoreServices::getInstance()->getResourceManager()->getResource(Resource::RESOURCE_CUBEMAP, pChild2->ToElement()->GetText()));
+								newShaderBinding->addCubemap(tname, (Cubemap*)CoreServices::getInstance()->getResourceManager()->getResource(Resource::RESOURCE_CUBEMAP, pChild2Element->GetText()));
 							}
 							
 						}

+ 4 - 1
Core/Contents/Source/PolyObject.cpp

@@ -266,8 +266,11 @@ void Object::createFromXMLElement(TiXmlElement *element, ObjectEntry *entry) {
 		String lastName = "";
 		int count = 0;
 		for (pChild = element->FirstChild(); pChild != 0; pChild = pChild->NextSibling()) {
+			TiXmlElement *pChildElement = pChild->ToElement();
+			if (!pChildElement) continue; // Skip comment nodes
+			
 			ObjectEntry *newEntry = new ObjectEntry();
-			createFromXMLElement(pChild->ToElement(), newEntry);
+			createFromXMLElement(pChildElement, newEntry);
 			entry->children.push_back(newEntry);		
 			if(newEntry->name == lastName) { // Keys cannot repeat in a CONTAINER
 				entry->type = ObjectEntry::ARRAY_ENTRY;

+ 4 - 2
Core/Contents/Source/PolyResourceManager.cpp

@@ -131,8 +131,10 @@ void ResourceManager::parseMaterials(const String& dirPath, bool recursive) {
 						TiXmlNode* pChild;					
 						for (pChild = mElem->FirstChild(); pChild != 0; pChild = pChild->NextSibling()) {
 							Material *newMat = CoreServices::getInstance()->getMaterialManager()->materialFromXMLNode(pChild);
-							newMat->setResourceName(newMat->getName());
-							resources.push_back(newMat);
+							if (newMat) {
+								newMat->setResourceName(newMat->getName());
+								resources.push_back(newMat);
+							}
 						}
 					}
 				}