소스 검색

[cpp] Fixed SkeletonBinary access violation if atlas and skeleton data mismatch (when attachment not found). Closes #1849.

Harald Csaszar 4 년 전
부모
커밋
2112d7f6f5
1개의 변경된 파일48개의 추가작업 그리고 7개의 파일을 삭제
  1. 48 7
      spine-cpp/spine-cpp/src/spine/SkeletonBinary.cpp

+ 48 - 7
spine-cpp/spine-cpp/src/spine/SkeletonBinary.cpp

@@ -281,8 +281,16 @@ SkeletonData *SkeletonBinary::readSkeletonData(const unsigned char *binary, cons
 	}
 	}
 
 
 	/* Skins. */
 	/* Skins. */
-	for (size_t i = 0, n = (size_t)readVarint(input, true); i < n; ++i)
-		skeletonData->_skins.add(readSkin(input, false, skeletonData, nonessential));
+	for (size_t i = 0, n = (size_t)readVarint(input, true); i < n; ++i) {
+		Skin* skin = readSkin(input, false, skeletonData, nonessential);
+		if (skin)
+			skeletonData->_skins.add(skin);
+		else {
+			delete input;
+			delete skeletonData;
+			return NULL;
+		}
+	}
 
 
 	/* Linked meshes. */
 	/* Linked meshes. */
 	for (int i = 0, n = _linkedMeshes.size(); i < n; ++i) {
 	for (int i = 0, n = _linkedMeshes.size(); i < n; ++i) {
@@ -470,7 +478,12 @@ Skin *SkeletonBinary::readSkin(DataInput *input, bool defaultSkin, SkeletonData
 		for (int ii = 0, nn = readVarint(input, true); ii < nn; ++ii) {
 		for (int ii = 0, nn = readVarint(input, true); ii < nn; ++ii) {
 			String name(readStringRef(input, skeletonData));
 			String name(readStringRef(input, skeletonData));
 			Attachment *attachment = readAttachment(input, skin, slotIndex, name, skeletonData, nonessential);
 			Attachment *attachment = readAttachment(input, skin, slotIndex, name, skeletonData, nonessential);
-			if (attachment) skin->setAttachment(slotIndex, String(name), attachment);
+			if (attachment)
+				skin->setAttachment(slotIndex, String(name), attachment);
+			else {
+				delete skin;
+				return nullptr;
+			}
 		}
 		}
 	}
 	}
 	return skin;
 	return skin;
@@ -488,6 +501,10 @@ Attachment *SkeletonBinary::readAttachment(DataInput *input, Skin *skin, int slo
 		String path(readStringRef(input, skeletonData));
 		String path(readStringRef(input, skeletonData));
 		if (path.isEmpty()) path = name;
 		if (path.isEmpty()) path = name;
 		RegionAttachment *region = _attachmentLoader->newRegionAttachment(*skin, String(name), String(path));
 		RegionAttachment *region = _attachmentLoader->newRegionAttachment(*skin, String(name), String(path));
+		if (!region) {
+			setError("Error reading attachment: ", name.buffer());
+			return nullptr;
+		}
 		region->_path = path;
 		region->_path = path;
 		region->_rotation = readFloat(input);
 		region->_rotation = readFloat(input);
 		region->_x = readFloat(input) * _scale;
 		region->_x = readFloat(input) * _scale;
@@ -504,6 +521,10 @@ Attachment *SkeletonBinary::readAttachment(DataInput *input, Skin *skin, int slo
 	case AttachmentType_Boundingbox: {
 	case AttachmentType_Boundingbox: {
 		int vertexCount = readVarint(input, true);
 		int vertexCount = readVarint(input, true);
 		BoundingBoxAttachment *box = _attachmentLoader->newBoundingBoxAttachment(*skin, String(name));
 		BoundingBoxAttachment *box = _attachmentLoader->newBoundingBoxAttachment(*skin, String(name));
+		if (!box) {
+			setError("Error reading attachment: ", name.buffer());
+			return nullptr;
+		}
 		readVertices(input, static_cast<VertexAttachment *>(box), vertexCount);
 		readVertices(input, static_cast<VertexAttachment *>(box), vertexCount);
 		if (nonessential) {
 		if (nonessential) {
 			/* Skip color. */
 			/* Skip color. */
@@ -519,6 +540,10 @@ Attachment *SkeletonBinary::readAttachment(DataInput *input, Skin *skin, int slo
 		if (path.isEmpty()) path = name;
 		if (path.isEmpty()) path = name;
 
 
 		mesh = _attachmentLoader->newMeshAttachment(*skin, String(name), String(path));
 		mesh = _attachmentLoader->newMeshAttachment(*skin, String(name), String(path));
+		if (!mesh) {
+			setError("Error reading attachment: ", name.buffer());
+			return nullptr;
+		}
 		mesh->_path = path;
 		mesh->_path = path;
 		readColor(input, mesh->getColor());
 		readColor(input, mesh->getColor());
 		vertexCount = readVarint(input, true);
 		vertexCount = readVarint(input, true);
@@ -543,6 +568,10 @@ Attachment *SkeletonBinary::readAttachment(DataInput *input, Skin *skin, int slo
 		if (path.isEmpty()) path = name;
 		if (path.isEmpty()) path = name;
 
 
 		MeshAttachment *mesh = _attachmentLoader->newMeshAttachment(*skin, String(name), String(path));
 		MeshAttachment *mesh = _attachmentLoader->newMeshAttachment(*skin, String(name), String(path));
+		if (!mesh) {
+			setError("Error reading attachment: ", name.buffer());
+			return nullptr;
+		}
 		mesh->_path = path;
 		mesh->_path = path;
 		readColor(input, mesh->getColor());
 		readColor(input, mesh->getColor());
 		String skinName(readStringRef(input, skeletonData));
 		String skinName(readStringRef(input, skeletonData));
@@ -559,7 +588,11 @@ Attachment *SkeletonBinary::readAttachment(DataInput *input, Skin *skin, int slo
 		return mesh;
 		return mesh;
 	}
 	}
 	case AttachmentType_Path: {
 	case AttachmentType_Path: {
-		PathAttachment *path = _attachmentLoader->newPathAttachment(*skin, String(name));
+		PathAttachment* path = _attachmentLoader->newPathAttachment(*skin, String(name));
+		if (!path) {
+			setError("Error reading attachment: ", name.buffer());
+			return nullptr;
+		}
 		path->_closed = readBoolean(input);
 		path->_closed = readBoolean(input);
 		path->_constantSpeed = readBoolean(input);
 		path->_constantSpeed = readBoolean(input);
 		int vertexCount = readVarint(input, true);
 		int vertexCount = readVarint(input, true);
@@ -577,7 +610,11 @@ Attachment *SkeletonBinary::readAttachment(DataInput *input, Skin *skin, int slo
 		return path;
 		return path;
 	}
 	}
 	case AttachmentType_Point: {
 	case AttachmentType_Point: {
-		PointAttachment *point = _attachmentLoader->newPointAttachment(*skin, String(name));
+		PointAttachment* point = _attachmentLoader->newPointAttachment(*skin, String(name));
+		if (!point) {
+			setError("Error reading attachment: ", name.buffer());
+			return nullptr;
+		}
 		point->_rotation = readFloat(input);
 		point->_rotation = readFloat(input);
 		point->_x = readFloat(input) * _scale;
 		point->_x = readFloat(input) * _scale;
 		point->_y = readFloat(input) * _scale;
 		point->_y = readFloat(input) * _scale;
@@ -592,7 +629,11 @@ Attachment *SkeletonBinary::readAttachment(DataInput *input, Skin *skin, int slo
 	case AttachmentType_Clipping: {
 	case AttachmentType_Clipping: {
 		int endSlotIndex = readVarint(input, true);
 		int endSlotIndex = readVarint(input, true);
 		int vertexCount = readVarint(input, true);
 		int vertexCount = readVarint(input, true);
-		ClippingAttachment *clip = _attachmentLoader->newClippingAttachment(*skin, name);
+		ClippingAttachment* clip = _attachmentLoader->newClippingAttachment(*skin, name);
+		if (!clip) {
+			setError("Error reading attachment: ", name.buffer());
+			return nullptr;
+		}
 		readVertices(input, static_cast<VertexAttachment *>(clip), vertexCount);
 		readVertices(input, static_cast<VertexAttachment *>(clip), vertexCount);
 		clip->_endSlot = skeletonData->_slots[endSlotIndex];
 		clip->_endSlot = skeletonData->_slots[endSlotIndex];
 		if (nonessential) {
 		if (nonessential) {
@@ -603,7 +644,7 @@ Attachment *SkeletonBinary::readAttachment(DataInput *input, Skin *skin, int slo
 		return clip;
 		return clip;
 	}
 	}
 	}
 	}
-	return NULL;
+	return nullptr;
 }
 }
 
 
 void SkeletonBinary::readVertices(DataInput *input, VertexAttachment *attachment, int vertexCount) {
 void SkeletonBinary::readVertices(DataInput *input, VertexAttachment *attachment, int vertexCount) {