[c] Closes #2258, check for empty skins in JSON parser

This commit is contained in:
Mario Zechner 2023-02-27 13:43:22 +01:00
parent a557db3a54
commit b0b1fe011e

View File

@ -1354,222 +1354,223 @@ spSkeletonData *spSkeletonJson_readSkeletonData(spSkeletonJson *self, const char
skeletonData->skins[skeletonData->skinsCount++] = skin; skeletonData->skins[skeletonData->skinsCount++] = skin;
if (strcmp(skin->name, "default") == 0) skeletonData->defaultSkin = skin; if (strcmp(skin->name, "default") == 0) skeletonData->defaultSkin = skin;
for (attachmentsMap = Json_getItem(skinMap, skinPart = Json_getItem(skinMap,"attachments");
"attachments") if (skinPart) {
->child; for (attachmentsMap = skinPart->child; attachmentsMap; attachmentsMap = attachmentsMap->next) {
attachmentsMap; attachmentsMap = attachmentsMap->next) { spSlotData *slot = spSkeletonData_findSlot(skeletonData, attachmentsMap->name);
spSlotData *slot = spSkeletonData_findSlot(skeletonData, attachmentsMap->name); Json *attachmentMap;
Json *attachmentMap;
for (attachmentMap = attachmentsMap->child; attachmentMap; attachmentMap = attachmentMap->next) { for (attachmentMap = attachmentsMap->child; attachmentMap; attachmentMap = attachmentMap->next) {
spAttachment *attachment; spAttachment *attachment;
const char *skinAttachmentName = attachmentMap->name; const char *skinAttachmentName = attachmentMap->name;
const char *attachmentName = Json_getString(attachmentMap, "name", skinAttachmentName); const char *attachmentName = Json_getString(attachmentMap, "name", skinAttachmentName);
const char *path = Json_getString(attachmentMap, "path", attachmentName); const char *path = Json_getString(attachmentMap, "path", attachmentName);
const char *color; const char *color;
Json *entry; Json *entry;
spSequence *sequence; spSequence *sequence;
const char *typeString = Json_getString(attachmentMap, "type", "region"); const char *typeString = Json_getString(attachmentMap, "type", "region");
spAttachmentType type; spAttachmentType type;
if (strcmp(typeString, "region") == 0) type = SP_ATTACHMENT_REGION; if (strcmp(typeString, "region") == 0) type = SP_ATTACHMENT_REGION;
else if (strcmp(typeString, "mesh") == 0) else if (strcmp(typeString, "mesh") == 0)
type = SP_ATTACHMENT_MESH; type = SP_ATTACHMENT_MESH;
else if (strcmp(typeString, "linkedmesh") == 0) else if (strcmp(typeString, "linkedmesh") == 0)
type = SP_ATTACHMENT_LINKED_MESH; type = SP_ATTACHMENT_LINKED_MESH;
else if (strcmp(typeString, "boundingbox") == 0) else if (strcmp(typeString, "boundingbox") == 0)
type = SP_ATTACHMENT_BOUNDING_BOX; type = SP_ATTACHMENT_BOUNDING_BOX;
else if (strcmp(typeString, "path") == 0) else if (strcmp(typeString, "path") == 0)
type = SP_ATTACHMENT_PATH; type = SP_ATTACHMENT_PATH;
else if (strcmp(typeString, "clipping") == 0) else if (strcmp(typeString, "clipping") == 0)
type = SP_ATTACHMENT_CLIPPING; type = SP_ATTACHMENT_CLIPPING;
else if (strcmp(typeString, "point") == 0) else if (strcmp(typeString, "point") == 0)
type = SP_ATTACHMENT_POINT; type = SP_ATTACHMENT_POINT;
else { else {
spSkeletonData_dispose(skeletonData); spSkeletonData_dispose(skeletonData);
_spSkeletonJson_setError(self, root, "Unknown attachment type: ", typeString); _spSkeletonJson_setError(self, root, "Unknown attachment type: ", typeString);
return NULL; return NULL;
} }
sequence = readSequence(Json_getItem(attachmentMap, "sequence")); sequence = readSequence(Json_getItem(attachmentMap, "sequence"));
attachment = spAttachmentLoader_createAttachment(self->attachmentLoader, skin, type, attachmentName, attachment = spAttachmentLoader_createAttachment(self->attachmentLoader, skin, type,
path, sequence); attachmentName,
if (!attachment) { path, sequence);
if (self->attachmentLoader->error1) { if (!attachment) {
spSkeletonData_dispose(skeletonData); if (self->attachmentLoader->error1) {
_spSkeletonJson_setError(self, root, self->attachmentLoader->error1, spSkeletonData_dispose(skeletonData);
self->attachmentLoader->error2); _spSkeletonJson_setError(self, root, self->attachmentLoader->error1,
return NULL; self->attachmentLoader->error2);
} return NULL;
continue; }
} continue;
}
switch (attachment->type) { switch (attachment->type) {
case SP_ATTACHMENT_REGION: { case SP_ATTACHMENT_REGION: {
spRegionAttachment *region = SUB_CAST(spRegionAttachment, attachment); spRegionAttachment *region = SUB_CAST(spRegionAttachment, attachment);
if (path) MALLOC_STR(region->path, path); if (path) MALLOC_STR(region->path, path);
region->x = Json_getFloat(attachmentMap, "x", 0) * self->scale; region->x = Json_getFloat(attachmentMap, "x", 0) * self->scale;
region->y = Json_getFloat(attachmentMap, "y", 0) * self->scale; region->y = Json_getFloat(attachmentMap, "y", 0) * self->scale;
region->scaleX = Json_getFloat(attachmentMap, "scaleX", 1); region->scaleX = Json_getFloat(attachmentMap, "scaleX", 1);
region->scaleY = Json_getFloat(attachmentMap, "scaleY", 1); region->scaleY = Json_getFloat(attachmentMap, "scaleY", 1);
region->rotation = Json_getFloat(attachmentMap, "rotation", 0); region->rotation = Json_getFloat(attachmentMap, "rotation", 0);
region->width = Json_getFloat(attachmentMap, "width", 32) * self->scale; region->width = Json_getFloat(attachmentMap, "width", 32) * self->scale;
region->height = Json_getFloat(attachmentMap, "height", 32) * self->scale; region->height = Json_getFloat(attachmentMap, "height", 32) * self->scale;
region->sequence = sequence; region->sequence = sequence;
color = Json_getString(attachmentMap, "color", 0); color = Json_getString(attachmentMap, "color", 0);
if (color) { if (color) {
spColor_setFromFloats(&region->color, spColor_setFromFloats(&region->color,
toColor(color, 0), toColor(color, 0),
toColor(color, 1), toColor(color, 1),
toColor(color, 2), toColor(color, 2),
toColor(color, 3)); toColor(color, 3));
} }
if (region->region != NULL) spRegionAttachment_updateRegion(region); if (region->region != NULL) spRegionAttachment_updateRegion(region);
spAttachmentLoader_configureAttachment(self->attachmentLoader, attachment); spAttachmentLoader_configureAttachment(self->attachmentLoader, attachment);
break; break;
} }
case SP_ATTACHMENT_MESH: case SP_ATTACHMENT_MESH:
case SP_ATTACHMENT_LINKED_MESH: { case SP_ATTACHMENT_LINKED_MESH: {
spMeshAttachment *mesh = SUB_CAST(spMeshAttachment, attachment); spMeshAttachment *mesh = SUB_CAST(spMeshAttachment, attachment);
MALLOC_STR(mesh->path, path); MALLOC_STR(mesh->path, path);
color = Json_getString(attachmentMap, "color", 0); color = Json_getString(attachmentMap, "color", 0);
if (color) { if (color) {
spColor_setFromFloats(&mesh->color, spColor_setFromFloats(&mesh->color,
toColor(color, 0), toColor(color, 0),
toColor(color, 1), toColor(color, 1),
toColor(color, 2), toColor(color, 2),
toColor(color, 3)); toColor(color, 3));
} }
mesh->width = Json_getFloat(attachmentMap, "width", 32) * self->scale; mesh->width = Json_getFloat(attachmentMap, "width", 32) * self->scale;
mesh->height = Json_getFloat(attachmentMap, "height", 32) * self->scale; mesh->height = Json_getFloat(attachmentMap, "height", 32) * self->scale;
mesh->sequence = sequence; mesh->sequence = sequence;
entry = Json_getItem(attachmentMap, "parent"); entry = Json_getItem(attachmentMap, "parent");
if (!entry) { if (!entry) {
int verticesLength; int verticesLength;
entry = Json_getItem(attachmentMap, "triangles"); entry = Json_getItem(attachmentMap, "triangles");
mesh->trianglesCount = entry->size; mesh->trianglesCount = entry->size;
mesh->triangles = MALLOC(unsigned short, entry->size); mesh->triangles = MALLOC(unsigned short, entry->size);
for (entry = entry->child, ii = 0; entry; entry = entry->next, ++ii) for (entry = entry->child, ii = 0; entry; entry = entry->next, ++ii)
mesh->triangles[ii] = (unsigned short) entry->valueInt; mesh->triangles[ii] = (unsigned short) entry->valueInt;
entry = Json_getItem(attachmentMap, "uvs"); entry = Json_getItem(attachmentMap, "uvs");
verticesLength = entry->size; verticesLength = entry->size;
mesh->regionUVs = MALLOC(float, verticesLength); mesh->regionUVs = MALLOC(float, verticesLength);
for (entry = entry->child, ii = 0; entry; entry = entry->next, ++ii) for (entry = entry->child, ii = 0; entry; entry = entry->next, ++ii)
mesh->regionUVs[ii] = entry->valueFloat; mesh->regionUVs[ii] = entry->valueFloat;
_readVertices(self, attachmentMap, SUPER(mesh), verticesLength); _readVertices(self, attachmentMap, SUPER(mesh), verticesLength);
if (mesh->region != NULL) spMeshAttachment_updateRegion(mesh); if (mesh->region != NULL) spMeshAttachment_updateRegion(mesh);
mesh->hullLength = Json_getInt(attachmentMap, "hull", 0); mesh->hullLength = Json_getInt(attachmentMap, "hull", 0);
entry = Json_getItem(attachmentMap, "edges"); entry = Json_getItem(attachmentMap, "edges");
if (entry) { if (entry) {
mesh->edgesCount = entry->size; mesh->edgesCount = entry->size;
mesh->edges = MALLOC(int, entry->size); mesh->edges = MALLOC(int, entry->size);
for (entry = entry->child, ii = 0; entry; entry = entry->next, ++ii) for (entry = entry->child, ii = 0; entry; entry = entry->next, ++ii)
mesh->edges[ii] = entry->valueInt; mesh->edges[ii] = entry->valueInt;
} }
spAttachmentLoader_configureAttachment(self->attachmentLoader, attachment); spAttachmentLoader_configureAttachment(self->attachmentLoader, attachment);
} else { } else {
int inheritTimelines = Json_getInt(attachmentMap, "timelines", 1); int inheritTimelines = Json_getInt(attachmentMap, "timelines", 1);
_spSkeletonJson_addLinkedMesh(self, SUB_CAST(spMeshAttachment, attachment), _spSkeletonJson_addLinkedMesh(self, SUB_CAST(spMeshAttachment, attachment),
Json_getString(attachmentMap, "skin", 0), slot->index, Json_getString(attachmentMap, "skin", 0), slot->index,
entry->valueString, inheritTimelines); entry->valueString, inheritTimelines);
} }
break; break;
} }
case SP_ATTACHMENT_BOUNDING_BOX: { case SP_ATTACHMENT_BOUNDING_BOX: {
spBoundingBoxAttachment *box = SUB_CAST(spBoundingBoxAttachment, attachment); spBoundingBoxAttachment *box = SUB_CAST(spBoundingBoxAttachment, attachment);
int vertexCount = Json_getInt(attachmentMap, "vertexCount", 0) << 1; int vertexCount = Json_getInt(attachmentMap, "vertexCount", 0) << 1;
_readVertices(self, attachmentMap, SUPER(box), vertexCount); _readVertices(self, attachmentMap, SUPER(box), vertexCount);
box->super.verticesCount = vertexCount; box->super.verticesCount = vertexCount;
color = Json_getString(attachmentMap, "color", 0); color = Json_getString(attachmentMap, "color", 0);
if (color) { if (color) {
spColor_setFromFloats(&box->color, spColor_setFromFloats(&box->color,
toColor(color, 0), toColor(color, 0),
toColor(color, 1), toColor(color, 1),
toColor(color, 2), toColor(color, 2),
toColor(color, 3)); toColor(color, 3));
} }
spAttachmentLoader_configureAttachment(self->attachmentLoader, attachment); spAttachmentLoader_configureAttachment(self->attachmentLoader, attachment);
break; break;
} }
case SP_ATTACHMENT_PATH: { case SP_ATTACHMENT_PATH: {
spPathAttachment *pathAttachment = SUB_CAST(spPathAttachment, attachment); spPathAttachment *pathAttachment = SUB_CAST(spPathAttachment, attachment);
int vertexCount = 0; int vertexCount = 0;
pathAttachment->closed = Json_getInt(attachmentMap, "closed", 0); pathAttachment->closed = Json_getInt(attachmentMap, "closed", 0);
pathAttachment->constantSpeed = Json_getInt(attachmentMap, "constantSpeed", 1); pathAttachment->constantSpeed = Json_getInt(attachmentMap, "constantSpeed", 1);
vertexCount = Json_getInt(attachmentMap, "vertexCount", 0); vertexCount = Json_getInt(attachmentMap, "vertexCount", 0);
_readVertices(self, attachmentMap, SUPER(pathAttachment), vertexCount << 1); _readVertices(self, attachmentMap, SUPER(pathAttachment), vertexCount << 1);
pathAttachment->lengthsLength = vertexCount / 3; pathAttachment->lengthsLength = vertexCount / 3;
pathAttachment->lengths = MALLOC(float, pathAttachment->lengthsLength); pathAttachment->lengths = MALLOC(float, pathAttachment->lengthsLength);
curves = Json_getItem(attachmentMap, "lengths"); curves = Json_getItem(attachmentMap, "lengths");
for (curves = curves->child, ii = 0; curves; curves = curves->next, ++ii) for (curves = curves->child, ii = 0; curves; curves = curves->next, ++ii)
pathAttachment->lengths[ii] = curves->valueFloat * self->scale; pathAttachment->lengths[ii] = curves->valueFloat * self->scale;
color = Json_getString(attachmentMap, "color", 0); color = Json_getString(attachmentMap, "color", 0);
if (color) { if (color) {
spColor_setFromFloats(&pathAttachment->color, spColor_setFromFloats(&pathAttachment->color,
toColor(color, 0), toColor(color, 0),
toColor(color, 1), toColor(color, 1),
toColor(color, 2), toColor(color, 2),
toColor(color, 3)); toColor(color, 3));
} }
break; break;
} }
case SP_ATTACHMENT_POINT: { case SP_ATTACHMENT_POINT: {
spPointAttachment *point = SUB_CAST(spPointAttachment, attachment); spPointAttachment *point = SUB_CAST(spPointAttachment, attachment);
point->x = Json_getFloat(attachmentMap, "x", 0) * self->scale; point->x = Json_getFloat(attachmentMap, "x", 0) * self->scale;
point->y = Json_getFloat(attachmentMap, "y", 0) * self->scale; point->y = Json_getFloat(attachmentMap, "y", 0) * self->scale;
point->rotation = Json_getFloat(attachmentMap, "rotation", 0); point->rotation = Json_getFloat(attachmentMap, "rotation", 0);
color = Json_getString(attachmentMap, "color", 0); color = Json_getString(attachmentMap, "color", 0);
if (color) { if (color) {
spColor_setFromFloats(&point->color, spColor_setFromFloats(&point->color,
toColor(color, 0), toColor(color, 0),
toColor(color, 1), toColor(color, 1),
toColor(color, 2), toColor(color, 2),
toColor(color, 3)); toColor(color, 3));
} }
break; break;
} }
case SP_ATTACHMENT_CLIPPING: { case SP_ATTACHMENT_CLIPPING: {
spClippingAttachment *clip = SUB_CAST(spClippingAttachment, attachment); spClippingAttachment *clip = SUB_CAST(spClippingAttachment, attachment);
int vertexCount = 0; int vertexCount = 0;
const char *end = Json_getString(attachmentMap, "end", 0); const char *end = Json_getString(attachmentMap, "end", 0);
if (end) { if (end) {
spSlotData *endSlot = spSkeletonData_findSlot(skeletonData, end); spSlotData *endSlot = spSkeletonData_findSlot(skeletonData, end);
clip->endSlot = endSlot; clip->endSlot = endSlot;
} }
vertexCount = Json_getInt(attachmentMap, "vertexCount", 0) << 1; vertexCount = Json_getInt(attachmentMap, "vertexCount", 0) << 1;
_readVertices(self, attachmentMap, SUPER(clip), vertexCount); _readVertices(self, attachmentMap, SUPER(clip), vertexCount);
color = Json_getString(attachmentMap, "color", 0); color = Json_getString(attachmentMap, "color", 0);
if (color) { if (color) {
spColor_setFromFloats(&clip->color, spColor_setFromFloats(&clip->color,
toColor(color, 0), toColor(color, 0),
toColor(color, 1), toColor(color, 1),
toColor(color, 2), toColor(color, 2),
toColor(color, 3)); toColor(color, 3));
} }
spAttachmentLoader_configureAttachment(self->attachmentLoader, attachment); spAttachmentLoader_configureAttachment(self->attachmentLoader, attachment);
break; break;
} }
} }
spSkin_setAttachment(skin, slot->index, skinAttachmentName, attachment); spSkin_setAttachment(skin, slot->index, skinAttachmentName, attachment);
} }
} }
}
} }
} }