mirror of
https://github.com/EsotericSoftware/spine-runtimes.git
synced 2025-12-21 09:46:02 +08:00
[spine-c] Fix crashes in skins or animations error handling (#2491)
* Fix android-specific rotation issue. bone->arotation == NaN, in some specific cases during update bones, cause squared value can been very smoll but still negative anyway and create NaN value * Fix crash at spSkeletonData_dispose() while handling problems in skeleton in SkeletonBinary/SkeletonJson. Use increase counts instead directly put counts value for avoid problems at early dispose vectors * additional commit for prev revision
This commit is contained in:
parent
07f299434d
commit
f67807f1e7
@ -1369,6 +1369,8 @@ spSkeletonData *spSkeletonBinary_readSkeletonData(spSkeletonBinary *self, const
|
|||||||
skeletonData->version = 0;
|
skeletonData->version = 0;
|
||||||
} else {
|
} else {
|
||||||
if (!string_starts_with(skeletonData->version, SPINE_VERSION_STRING)) {
|
if (!string_starts_with(skeletonData->version, SPINE_VERSION_STRING)) {
|
||||||
|
FREE(input);
|
||||||
|
spSkeletonData_dispose(skeletonData);
|
||||||
char errorMsg[255];
|
char errorMsg[255];
|
||||||
snprintf(errorMsg, 255, "Skeleton version %s does not match runtime version %s", skeletonData->version, SPINE_VERSION_STRING);
|
snprintf(errorMsg, 255, "Skeleton version %s does not match runtime version %s", skeletonData->version, SPINE_VERSION_STRING);
|
||||||
_spSkeletonBinary_setError(self, errorMsg, NULL);
|
_spSkeletonBinary_setError(self, errorMsg, NULL);
|
||||||
@ -1596,6 +1598,8 @@ spSkeletonData *spSkeletonBinary_readSkeletonData(spSkeletonBinary *self, const
|
|||||||
/* Default skin. */
|
/* Default skin. */
|
||||||
skeletonData->defaultSkin = spSkeletonBinary_readSkin(self, input, -1, skeletonData, nonessential);
|
skeletonData->defaultSkin = spSkeletonBinary_readSkin(self, input, -1, skeletonData, nonessential);
|
||||||
if (self->attachmentLoader->error1) {
|
if (self->attachmentLoader->error1) {
|
||||||
|
FREE(input);
|
||||||
|
spSkin_dispose(skeletonData->defaultSkin);
|
||||||
spSkeletonData_dispose(skeletonData);
|
spSkeletonData_dispose(skeletonData);
|
||||||
_spSkeletonBinary_setError(self, self->attachmentLoader->error1, self->attachmentLoader->error2);
|
_spSkeletonBinary_setError(self, self->attachmentLoader->error1, self->attachmentLoader->error2);
|
||||||
return NULL;
|
return NULL;
|
||||||
@ -1614,6 +1618,8 @@ spSkeletonData *spSkeletonBinary_readSkeletonData(spSkeletonBinary *self, const
|
|||||||
for (i = skeletonData->defaultSkin ? 1 : 0; i < skeletonData->skinsCount; ++i) {
|
for (i = skeletonData->defaultSkin ? 1 : 0; i < skeletonData->skinsCount; ++i) {
|
||||||
spSkin *skin = spSkeletonBinary_readSkin(self, input, 0, skeletonData, nonessential);
|
spSkin *skin = spSkeletonBinary_readSkin(self, input, 0, skeletonData, nonessential);
|
||||||
if (self->attachmentLoader->error1) {
|
if (self->attachmentLoader->error1) {
|
||||||
|
FREE(input);
|
||||||
|
skeletonData->skinsCount = i + 1;
|
||||||
spSkeletonData_dispose(skeletonData);
|
spSkeletonData_dispose(skeletonData);
|
||||||
_spSkeletonBinary_setError(self, self->attachmentLoader->error1, self->attachmentLoader->error2);
|
_spSkeletonBinary_setError(self, self->attachmentLoader->error1, self->attachmentLoader->error2);
|
||||||
return NULL;
|
return NULL;
|
||||||
@ -1672,6 +1678,7 @@ spSkeletonData *spSkeletonBinary_readSkeletonData(spSkeletonBinary *self, const
|
|||||||
FREE(name);
|
FREE(name);
|
||||||
if (!animation) {
|
if (!animation) {
|
||||||
FREE(input);
|
FREE(input);
|
||||||
|
skeletonData->animationsCount = i + 1;
|
||||||
spSkeletonData_dispose(skeletonData);
|
spSkeletonData_dispose(skeletonData);
|
||||||
_spSkeletonBinary_setError(self, "Animation corrupted: ", name);
|
_spSkeletonBinary_setError(self, "Animation corrupted: ", name);
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|||||||
@ -1177,7 +1177,6 @@ spSkeletonData *spSkeletonJson_readSkeletonData(spSkeletonJson *self, const char
|
|||||||
slots = Json_getItem(root, "slots");
|
slots = Json_getItem(root, "slots");
|
||||||
if (slots) {
|
if (slots) {
|
||||||
Json *slotMap;
|
Json *slotMap;
|
||||||
skeletonData->slotsCount = slots->size;
|
|
||||||
skeletonData->slots = MALLOC(spSlotData *, slots->size);
|
skeletonData->slots = MALLOC(spSlotData *, slots->size);
|
||||||
for (slotMap = slots->child, i = 0; slotMap; slotMap = slotMap->next, ++i) {
|
for (slotMap = slots->child, i = 0; slotMap; slotMap = slotMap->next, ++i) {
|
||||||
spSlotData *data;
|
spSlotData *data;
|
||||||
@ -1237,6 +1236,7 @@ spSkeletonData *spSkeletonJson_readSkeletonData(spSkeletonJson *self, const char
|
|||||||
data->visible = Json_getInt(slotMap, "visible", -1);
|
data->visible = Json_getInt(slotMap, "visible", -1);
|
||||||
data->path = pathName;
|
data->path = pathName;
|
||||||
skeletonData->slots[i] = data;
|
skeletonData->slots[i] = data;
|
||||||
|
skeletonData->slotsCount++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1244,7 +1244,6 @@ spSkeletonData *spSkeletonJson_readSkeletonData(spSkeletonJson *self, const char
|
|||||||
ik = Json_getItem(root, "ik");
|
ik = Json_getItem(root, "ik");
|
||||||
if (ik) {
|
if (ik) {
|
||||||
Json *constraintMap;
|
Json *constraintMap;
|
||||||
skeletonData->ikConstraintsCount = ik->size;
|
|
||||||
skeletonData->ikConstraints = MALLOC(spIkConstraintData *, ik->size);
|
skeletonData->ikConstraints = MALLOC(spIkConstraintData *, ik->size);
|
||||||
for (constraintMap = ik->child, i = 0; constraintMap; constraintMap = constraintMap->next, ++i) {
|
for (constraintMap = ik->child, i = 0; constraintMap; constraintMap = constraintMap->next, ++i) {
|
||||||
const char *targetName;
|
const char *targetName;
|
||||||
@ -1259,6 +1258,7 @@ spSkeletonData *spSkeletonJson_readSkeletonData(spSkeletonJson *self, const char
|
|||||||
for (boneMap = boneMap->child, ii = 0; boneMap; boneMap = boneMap->next, ++ii) {
|
for (boneMap = boneMap->child, ii = 0; boneMap; boneMap = boneMap->next, ++ii) {
|
||||||
data->bones[ii] = spSkeletonData_findBone(skeletonData, boneMap->valueString);
|
data->bones[ii] = spSkeletonData_findBone(skeletonData, boneMap->valueString);
|
||||||
if (!data->bones[ii]) {
|
if (!data->bones[ii]) {
|
||||||
|
spIkConstraintData_dispose(data);
|
||||||
spSkeletonData_dispose(skeletonData);
|
spSkeletonData_dispose(skeletonData);
|
||||||
_spSkeletonJson_setError(self, root, "IK bone not found: ", boneMap->valueString);
|
_spSkeletonJson_setError(self, root, "IK bone not found: ", boneMap->valueString);
|
||||||
return NULL;
|
return NULL;
|
||||||
@ -1268,6 +1268,7 @@ spSkeletonData *spSkeletonJson_readSkeletonData(spSkeletonJson *self, const char
|
|||||||
targetName = Json_getString(constraintMap, "target", 0);
|
targetName = Json_getString(constraintMap, "target", 0);
|
||||||
data->target = spSkeletonData_findBone(skeletonData, targetName);
|
data->target = spSkeletonData_findBone(skeletonData, targetName);
|
||||||
if (!data->target) {
|
if (!data->target) {
|
||||||
|
spIkConstraintData_dispose(data);
|
||||||
spSkeletonData_dispose(skeletonData);
|
spSkeletonData_dispose(skeletonData);
|
||||||
_spSkeletonJson_setError(self, root, "Target bone not found: ", targetName);
|
_spSkeletonJson_setError(self, root, "Target bone not found: ", targetName);
|
||||||
return NULL;
|
return NULL;
|
||||||
@ -1281,6 +1282,7 @@ spSkeletonData *spSkeletonJson_readSkeletonData(spSkeletonJson *self, const char
|
|||||||
data->softness = Json_getFloat(constraintMap, "softness", 0) * self->scale;
|
data->softness = Json_getFloat(constraintMap, "softness", 0) * self->scale;
|
||||||
|
|
||||||
skeletonData->ikConstraints[i] = data;
|
skeletonData->ikConstraints[i] = data;
|
||||||
|
skeletonData->ikConstraintsCount++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1288,7 +1290,6 @@ spSkeletonData *spSkeletonJson_readSkeletonData(spSkeletonJson *self, const char
|
|||||||
transform = Json_getItem(root, "transform");
|
transform = Json_getItem(root, "transform");
|
||||||
if (transform) {
|
if (transform) {
|
||||||
Json *constraintMap;
|
Json *constraintMap;
|
||||||
skeletonData->transformConstraintsCount = transform->size;
|
|
||||||
skeletonData->transformConstraints = MALLOC(spTransformConstraintData *, transform->size);
|
skeletonData->transformConstraints = MALLOC(spTransformConstraintData *, transform->size);
|
||||||
for (constraintMap = transform->child, i = 0; constraintMap; constraintMap = constraintMap->next, ++i) {
|
for (constraintMap = transform->child, i = 0; constraintMap; constraintMap = constraintMap->next, ++i) {
|
||||||
const char *name;
|
const char *name;
|
||||||
@ -1304,6 +1305,7 @@ spSkeletonData *spSkeletonJson_readSkeletonData(spSkeletonJson *self, const char
|
|||||||
for (boneMap = boneMap->child, ii = 0; boneMap; boneMap = boneMap->next, ++ii) {
|
for (boneMap = boneMap->child, ii = 0; boneMap; boneMap = boneMap->next, ++ii) {
|
||||||
data->bones[ii] = spSkeletonData_findBone(skeletonData, boneMap->valueString);
|
data->bones[ii] = spSkeletonData_findBone(skeletonData, boneMap->valueString);
|
||||||
if (!data->bones[ii]) {
|
if (!data->bones[ii]) {
|
||||||
|
spTransformConstraintData_dispose(data);
|
||||||
spSkeletonData_dispose(skeletonData);
|
spSkeletonData_dispose(skeletonData);
|
||||||
_spSkeletonJson_setError(self, root, "Transform bone not found: ", boneMap->valueString);
|
_spSkeletonJson_setError(self, root, "Transform bone not found: ", boneMap->valueString);
|
||||||
return NULL;
|
return NULL;
|
||||||
@ -1313,6 +1315,7 @@ spSkeletonData *spSkeletonJson_readSkeletonData(spSkeletonJson *self, const char
|
|||||||
name = Json_getString(constraintMap, "target", 0);
|
name = Json_getString(constraintMap, "target", 0);
|
||||||
data->target = spSkeletonData_findBone(skeletonData, name);
|
data->target = spSkeletonData_findBone(skeletonData, name);
|
||||||
if (!data->target) {
|
if (!data->target) {
|
||||||
|
spTransformConstraintData_dispose(data);
|
||||||
spSkeletonData_dispose(skeletonData);
|
spSkeletonData_dispose(skeletonData);
|
||||||
_spSkeletonJson_setError(self, root, "Target bone not found: ", name);
|
_spSkeletonJson_setError(self, root, "Target bone not found: ", name);
|
||||||
return NULL;
|
return NULL;
|
||||||
@ -1335,6 +1338,7 @@ spSkeletonData *spSkeletonJson_readSkeletonData(spSkeletonJson *self, const char
|
|||||||
data->mixShearY = Json_getFloat(constraintMap, "mixShearY", 1);
|
data->mixShearY = Json_getFloat(constraintMap, "mixShearY", 1);
|
||||||
|
|
||||||
skeletonData->transformConstraints[i] = data;
|
skeletonData->transformConstraints[i] = data;
|
||||||
|
skeletonData->transformConstraintsCount++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1342,7 +1346,6 @@ spSkeletonData *spSkeletonJson_readSkeletonData(spSkeletonJson *self, const char
|
|||||||
pathJson = Json_getItem(root, "path");
|
pathJson = Json_getItem(root, "path");
|
||||||
if (pathJson) {
|
if (pathJson) {
|
||||||
Json *constraintMap;
|
Json *constraintMap;
|
||||||
skeletonData->pathConstraintsCount = pathJson->size;
|
|
||||||
skeletonData->pathConstraints = MALLOC(spPathConstraintData *, pathJson->size);
|
skeletonData->pathConstraints = MALLOC(spPathConstraintData *, pathJson->size);
|
||||||
for (constraintMap = pathJson->child, i = 0; constraintMap; constraintMap = constraintMap->next, ++i) {
|
for (constraintMap = pathJson->child, i = 0; constraintMap; constraintMap = constraintMap->next, ++i) {
|
||||||
const char *name;
|
const char *name;
|
||||||
@ -1358,6 +1361,7 @@ spSkeletonData *spSkeletonJson_readSkeletonData(spSkeletonJson *self, const char
|
|||||||
for (boneMap = boneMap->child, ii = 0; boneMap; boneMap = boneMap->next, ++ii) {
|
for (boneMap = boneMap->child, ii = 0; boneMap; boneMap = boneMap->next, ++ii) {
|
||||||
data->bones[ii] = spSkeletonData_findBone(skeletonData, boneMap->valueString);
|
data->bones[ii] = spSkeletonData_findBone(skeletonData, boneMap->valueString);
|
||||||
if (!data->bones[ii]) {
|
if (!data->bones[ii]) {
|
||||||
|
spPathConstraintData_dispose(data);
|
||||||
spSkeletonData_dispose(skeletonData);
|
spSkeletonData_dispose(skeletonData);
|
||||||
_spSkeletonJson_setError(self, root, "Path bone not found: ", boneMap->valueString);
|
_spSkeletonJson_setError(self, root, "Path bone not found: ", boneMap->valueString);
|
||||||
return NULL;
|
return NULL;
|
||||||
@ -1367,6 +1371,7 @@ spSkeletonData *spSkeletonJson_readSkeletonData(spSkeletonJson *self, const char
|
|||||||
name = Json_getString(constraintMap, "target", 0);
|
name = Json_getString(constraintMap, "target", 0);
|
||||||
data->target = spSkeletonData_findSlot(skeletonData, name);
|
data->target = spSkeletonData_findSlot(skeletonData, name);
|
||||||
if (!data->target) {
|
if (!data->target) {
|
||||||
|
spPathConstraintData_dispose(data);
|
||||||
spSkeletonData_dispose(skeletonData);
|
spSkeletonData_dispose(skeletonData);
|
||||||
_spSkeletonJson_setError(self, root, "Target slot not found: ", name);
|
_spSkeletonJson_setError(self, root, "Target slot not found: ", name);
|
||||||
return NULL;
|
return NULL;
|
||||||
@ -1404,6 +1409,7 @@ spSkeletonData *spSkeletonJson_readSkeletonData(spSkeletonJson *self, const char
|
|||||||
data->mixY = Json_getFloat(constraintMap, "mixY", data->mixX);
|
data->mixY = Json_getFloat(constraintMap, "mixY", data->mixX);
|
||||||
|
|
||||||
skeletonData->pathConstraints[i] = data;
|
skeletonData->pathConstraints[i] = data;
|
||||||
|
skeletonData->pathConstraintsCount++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1471,6 +1477,7 @@ spSkeletonData *spSkeletonJson_readSkeletonData(spSkeletonJson *self, const char
|
|||||||
for (skinPart = skinPart->child; skinPart; skinPart = skinPart->next) {
|
for (skinPart = skinPart->child; skinPart; skinPart = skinPart->next) {
|
||||||
spBoneData *bone = spSkeletonData_findBone(skeletonData, skinPart->valueString);
|
spBoneData *bone = spSkeletonData_findBone(skeletonData, skinPart->valueString);
|
||||||
if (!bone) {
|
if (!bone) {
|
||||||
|
spSkin_dispose(skin);
|
||||||
spSkeletonData_dispose(skeletonData);
|
spSkeletonData_dispose(skeletonData);
|
||||||
_spSkeletonJson_setError(self, root, "Skin bone constraint not found: ", skinPart->valueString);
|
_spSkeletonJson_setError(self, root, "Skin bone constraint not found: ", skinPart->valueString);
|
||||||
return NULL;
|
return NULL;
|
||||||
@ -1485,6 +1492,7 @@ spSkeletonData *spSkeletonJson_readSkeletonData(spSkeletonJson *self, const char
|
|||||||
spIkConstraintData *constraint = spSkeletonData_findIkConstraint(skeletonData,
|
spIkConstraintData *constraint = spSkeletonData_findIkConstraint(skeletonData,
|
||||||
skinPart->valueString);
|
skinPart->valueString);
|
||||||
if (!constraint) {
|
if (!constraint) {
|
||||||
|
spSkin_dispose(skin);
|
||||||
spSkeletonData_dispose(skeletonData);
|
spSkeletonData_dispose(skeletonData);
|
||||||
_spSkeletonJson_setError(self, root, "Skin IK constraint not found: ", skinPart->valueString);
|
_spSkeletonJson_setError(self, root, "Skin IK constraint not found: ", skinPart->valueString);
|
||||||
return NULL;
|
return NULL;
|
||||||
@ -1499,6 +1507,7 @@ spSkeletonData *spSkeletonJson_readSkeletonData(spSkeletonJson *self, const char
|
|||||||
spPathConstraintData *constraint = spSkeletonData_findPathConstraint(skeletonData,
|
spPathConstraintData *constraint = spSkeletonData_findPathConstraint(skeletonData,
|
||||||
skinPart->valueString);
|
skinPart->valueString);
|
||||||
if (!constraint) {
|
if (!constraint) {
|
||||||
|
spSkin_dispose(skin);
|
||||||
spSkeletonData_dispose(skeletonData);
|
spSkeletonData_dispose(skeletonData);
|
||||||
_spSkeletonJson_setError(self, root, "Skin path constraint not found: ", skinPart->valueString);
|
_spSkeletonJson_setError(self, root, "Skin path constraint not found: ", skinPart->valueString);
|
||||||
return NULL;
|
return NULL;
|
||||||
@ -1513,6 +1522,7 @@ spSkeletonData *spSkeletonJson_readSkeletonData(spSkeletonJson *self, const char
|
|||||||
spTransformConstraintData *constraint = spSkeletonData_findTransformConstraint(skeletonData,
|
spTransformConstraintData *constraint = spSkeletonData_findTransformConstraint(skeletonData,
|
||||||
skinPart->valueString);
|
skinPart->valueString);
|
||||||
if (!constraint) {
|
if (!constraint) {
|
||||||
|
spSkin_dispose(skin);
|
||||||
spSkeletonData_dispose(skeletonData);
|
spSkeletonData_dispose(skeletonData);
|
||||||
_spSkeletonJson_setError(self, root, "Skin transform constraint not found: ",
|
_spSkeletonJson_setError(self, root, "Skin transform constraint not found: ",
|
||||||
skinPart->valueString);
|
skinPart->valueString);
|
||||||
@ -1766,13 +1776,13 @@ spSkeletonData *spSkeletonJson_readSkeletonData(spSkeletonJson *self, const char
|
|||||||
spSkin *skin = !linkedMesh->skin ? skeletonData->defaultSkin : spSkeletonData_findSkin(skeletonData, linkedMesh->skin);
|
spSkin *skin = !linkedMesh->skin ? skeletonData->defaultSkin : spSkeletonData_findSkin(skeletonData, linkedMesh->skin);
|
||||||
if (!skin) {
|
if (!skin) {
|
||||||
spSkeletonData_dispose(skeletonData);
|
spSkeletonData_dispose(skeletonData);
|
||||||
_spSkeletonJson_setError(self, 0, "Skin not found: ", linkedMesh->skin);
|
_spSkeletonJson_setError(self, root, "Skin not found: ", linkedMesh->skin);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
parent = spSkin_getAttachment(skin, linkedMesh->slotIndex, linkedMesh->parent);
|
parent = spSkin_getAttachment(skin, linkedMesh->slotIndex, linkedMesh->parent);
|
||||||
if (!parent) {
|
if (!parent) {
|
||||||
spSkeletonData_dispose(skeletonData);
|
spSkeletonData_dispose(skeletonData);
|
||||||
_spSkeletonJson_setError(self, 0, "Parent mesh not found: ", linkedMesh->parent);
|
_spSkeletonJson_setError(self, root, "Parent mesh not found: ", linkedMesh->parent);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
linkedMesh->mesh->super.timelineAttachment = linkedMesh->inheritTimeline ? parent
|
linkedMesh->mesh->super.timelineAttachment = linkedMesh->inheritTimeline ? parent
|
||||||
@ -1815,6 +1825,7 @@ spSkeletonData *spSkeletonJson_readSkeletonData(spSkeletonJson *self, const char
|
|||||||
spAnimation *animation = _spSkeletonJson_readAnimation(self, animationMap, skeletonData);
|
spAnimation *animation = _spSkeletonJson_readAnimation(self, animationMap, skeletonData);
|
||||||
if (!animation) {
|
if (!animation) {
|
||||||
spSkeletonData_dispose(skeletonData);
|
spSkeletonData_dispose(skeletonData);
|
||||||
|
_spSkeletonJson_setError(self, root, "Animation broken: ", animationMap->name);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
skeletonData->animations[skeletonData->animationsCount++] = animation;
|
skeletonData->animations[skeletonData->animationsCount++] = animation;
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user