From 5989c861caaaa1fa89a5ff28bced4a5d795d523a Mon Sep 17 00:00:00 2001 From: Mario Zechner Date: Thu, 19 Oct 2023 19:43:59 +0200 Subject: [PATCH 1/3] [c] Closes #2397, buffer overflow when loading sequences with less than 10 frames. --- spine-c/spine-c/src/spine/AtlasAttachmentLoader.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/spine-c/spine-c/src/spine/AtlasAttachmentLoader.c b/spine-c/spine-c/src/spine/AtlasAttachmentLoader.c index 7a814b085..3d3d6ce6d 100644 --- a/spine-c/spine-c/src/spine/AtlasAttachmentLoader.c +++ b/spine-c/spine-c/src/spine/AtlasAttachmentLoader.c @@ -33,7 +33,7 @@ static int /*bool*/ loadSequence(spAtlas *atlas, const char *basePath, spSequence *sequence) { spTextureRegionArray *regions = sequence->regions; - char *path = CALLOC(char, strlen(basePath) + sequence->digits + 1); + char *path = CALLOC(char, strlen(basePath) + sequence->digits + 2); int i; for (i = 0; i < regions->size; i++) { spSequence_getPath(sequence, basePath, i, path); From c960402c08ae6814ac55cd2e3675a587977f424a Mon Sep 17 00:00:00 2001 From: Mario Zechner Date: Mon, 23 Oct 2023 13:18:04 +0200 Subject: [PATCH 2/3] [c] Closes #2401, fixed incorrect allocation of TransformTimeline. --- .../spine-cpp/src/spine/SkeletonJson.cpp | 2 +- spine-sfml/cpp/example/testbed.cpp | 73 ++++++++++++++++--- .../SpinePlugin/Private/SpineAtlasAsset.cpp | 6 +- .../Private/SpineSkeletonDataAsset.cpp | 14 ++-- .../SpinePlugin/Public/SpineAtlasAsset.h | 2 +- .../Public/SpineSkeletonDataAsset.h | 2 +- 6 files changed, 75 insertions(+), 24 deletions(-) diff --git a/spine-cpp/spine-cpp/src/spine/SkeletonJson.cpp b/spine-cpp/spine-cpp/src/spine/SkeletonJson.cpp index cb41df4c0..ac21f0ab7 100644 --- a/spine-cpp/spine-cpp/src/spine/SkeletonJson.cpp +++ b/spine-cpp/spine-cpp/src/spine/SkeletonJson.cpp @@ -1144,7 +1144,7 @@ Animation *SkeletonJson::readAnimation(Json *root, SkeletonData *skeletonData) { TransformConstraintData *constraint = skeletonData->findTransformConstraint(constraintMap->_name); int constraintIndex = skeletonData->_transformConstraints.indexOf(constraint); TransformConstraintTimeline *timeline = new (__FILE__, __LINE__) TransformConstraintTimeline( - constraintMap->_size, constraintMap->_size << 2, constraintIndex); + constraintMap->_size, constraintMap->_size * 6, constraintIndex); float time = Json::getFloat(keyMap, "time", 0); float mixRotate = Json::getFloat(keyMap, "mixRotate", 1); diff --git a/spine-sfml/cpp/example/testbed.cpp b/spine-sfml/cpp/example/testbed.cpp index 080e509d2..a883ba146 100644 --- a/spine-sfml/cpp/example/testbed.cpp +++ b/spine-sfml/cpp/example/testbed.cpp @@ -33,27 +33,78 @@ using namespace spine; +class NullTextureLoader : public TextureLoader { +public: + virtual void load(AtlasPage &page, const String &path) {} + + virtual void unload(void *texture) {} +}; + +class NullAttachmentLoader : public AttachmentLoader { + virtual RegionAttachment *newRegionAttachment(Skin &skin, const String &name, const String &path, Sequence *sequence) { + return new (__FILE__, __LINE__) RegionAttachment(name); + } + + virtual MeshAttachment *newMeshAttachment(Skin &skin, const String &name, const String &path, Sequence *sequence) { + return new (__FILE__, __LINE__) MeshAttachment(name); + } + + virtual BoundingBoxAttachment *newBoundingBoxAttachment(Skin &skin, const String &name) { + return new (__FILE__, __LINE__) BoundingBoxAttachment(name); + } + + virtual PathAttachment *newPathAttachment(Skin &skin, const String &name) { + return new (__FILE__, __LINE__) PathAttachment(name); + } + + virtual PointAttachment *newPointAttachment(Skin &skin, const String &name) { + return new (__FILE__, __LINE__) PointAttachment(name); + } + + virtual ClippingAttachment *newClippingAttachment(Skin &skin, const String &name) { + return new (__FILE__, __LINE__) ClippingAttachment(name); + } + + virtual void configureAttachment(Attachment *attachment) { + } +}; + int main(void) { - String atlasFile("data/spineboy-pma.atlas"); - String skeletonFile("data/spineboy-pro.skel"); + String atlasFile(""); + String skeletonFile("/Users/badlogic/Downloads/catsanddogs2.json"); + String animation = ""; + float scale = 0.6f; SFMLTextureLoader textureLoader; - Atlas *atlas = new Atlas(atlasFile, &textureLoader); + NullAttachmentLoader nullLoader; + Atlas *atlas = atlasFile.length() == 0 ? nullptr : new Atlas(atlasFile, &textureLoader); SkeletonData *skeletonData = nullptr; - if (strncmp(skeletonFile.buffer(), ".skel", skeletonFile.length()) > 0) { - SkeletonBinary binary(atlas); - binary.setScale(scale); - skeletonData = binary.readSkeletonDataFile(skeletonFile); + if (strnstr(skeletonFile.buffer(), ".skel", skeletonFile.length()) != nullptr) { + SkeletonBinary *binary = nullptr; + if (atlas) { + binary = new SkeletonBinary(atlas); + } else { + binary = new SkeletonBinary(&nullLoader); + } + binary->setScale(scale); + skeletonData = binary->readSkeletonDataFile(skeletonFile); + delete binary; } else { - SkeletonJson json(atlas); - json.setScale(scale); - skeletonData = json.readSkeletonDataFile(skeletonFile); + SkeletonJson *json = nullptr; + if (atlas) { + json = new SkeletonJson(atlas); + } else { + json = new SkeletonJson(&nullLoader); + } + json->setScale(scale); + skeletonData = json->readSkeletonDataFile(skeletonFile); + delete json; } AnimationStateData stateData(skeletonData); SkeletonDrawable drawable(skeletonData, &stateData); drawable.skeleton->setPosition(320, 590); - drawable.state->setAnimation(0, "walk", true); + if (animation.length() > 0) drawable.state->setAnimation(0, animation, true); sf::RenderWindow window(sf::VideoMode(640, 640), "Spine SFML - testbed"); window.setFramerateLimit(60); diff --git a/spine-ue4/Plugins/SpinePlugin/Source/SpinePlugin/Private/SpineAtlasAsset.cpp b/spine-ue4/Plugins/SpinePlugin/Source/SpinePlugin/Private/SpineAtlasAsset.cpp index d80d1e11a..c1759eed7 100644 --- a/spine-ue4/Plugins/SpinePlugin/Source/SpinePlugin/Private/SpineAtlasAsset.cpp +++ b/spine-ue4/Plugins/SpinePlugin/Source/SpinePlugin/Private/SpineAtlasAsset.cpp @@ -58,13 +58,13 @@ void USpineAtlasAsset::Serialize(FArchive &Ar) { importData = NewObject(this, TEXT("AssetImportData")); } -void USpineAtlasAsset::PostLoadAssetRegistryTags(const FAssetData& InAssetData, - TArray& OutTagsAndValuesToUpdate) const { +void USpineAtlasAsset::PostLoadAssetRegistryTags(const FAssetData &InAssetData, + TArray &OutTagsAndValuesToUpdate) const { // FIXME: this is a massive hack. It will set the PackageFlags of the FAssetData // in the AssetRegistry to PKG_FilterEditorOnly so the content browser displays it. // This is necessary in UE 5.3 due to a regression in ContentBrowserAssetDataCore::IsPrimaryAsset // See https://github.com/EsotericSoftware/spine-runtimes/issues/2368 - FAssetData& MutableAssetData = const_cast(InAssetData); + FAssetData &MutableAssetData = const_cast(InAssetData); // MutableAssetData.PackageFlags = EPackageFlags::PKG_FilterEditorOnly; UObject::PostLoadAssetRegistryTags(MutableAssetData, OutTagsAndValuesToUpdate); } diff --git a/spine-ue4/Plugins/SpinePlugin/Source/SpinePlugin/Private/SpineSkeletonDataAsset.cpp b/spine-ue4/Plugins/SpinePlugin/Source/SpinePlugin/Private/SpineSkeletonDataAsset.cpp index d95094bb9..55e87afab 100644 --- a/spine-ue4/Plugins/SpinePlugin/Source/SpinePlugin/Private/SpineSkeletonDataAsset.cpp +++ b/spine-ue4/Plugins/SpinePlugin/Source/SpinePlugin/Private/SpineSkeletonDataAsset.cpp @@ -81,13 +81,13 @@ void USpineSkeletonDataAsset::Serialize(FArchive &Ar) { } -void USpineSkeletonDataAsset::PostLoadAssetRegistryTags(const FAssetData& InAssetData, - // FIXME: this is a massive hack. It will set the PackageFlags of the FAssetData - // in the AssetRegistry to PKG_FilterEditorOnly so the content browser displays it. - // This is necessary in UE 5.3 due to a regression in ContentBrowserAssetDataCore::IsPrimaryAsset - // See https://github.com/EsotericSoftware/spine-runtimes/issues/2368 - TArray& OutTagsAndValuesToUpdate) const { - FAssetData& MutableAssetData = const_cast(InAssetData); +void USpineSkeletonDataAsset::PostLoadAssetRegistryTags(const FAssetData &InAssetData, + // FIXME: this is a massive hack. It will set the PackageFlags of the FAssetData + // in the AssetRegistry to PKG_FilterEditorOnly so the content browser displays it. + // This is necessary in UE 5.3 due to a regression in ContentBrowserAssetDataCore::IsPrimaryAsset + // See https://github.com/EsotericSoftware/spine-runtimes/issues/2368 + TArray &OutTagsAndValuesToUpdate) const { + FAssetData &MutableAssetData = const_cast(InAssetData); // MutableAssetData.PackageFlags = EPackageFlags::PKG_FilterEditorOnly; UObject::PostLoadAssetRegistryTags(MutableAssetData, OutTagsAndValuesToUpdate); } diff --git a/spine-ue4/Plugins/SpinePlugin/Source/SpinePlugin/Public/SpineAtlasAsset.h b/spine-ue4/Plugins/SpinePlugin/Source/SpinePlugin/Public/SpineAtlasAsset.h index b6a22a808..8b0500ac9 100644 --- a/spine-ue4/Plugins/SpinePlugin/Source/SpinePlugin/Public/SpineAtlasAsset.h +++ b/spine-ue4/Plugins/SpinePlugin/Source/SpinePlugin/Public/SpineAtlasAsset.h @@ -71,6 +71,6 @@ protected: virtual void PostInitProperties() override; virtual void Serialize(FArchive &Ar) override; - virtual void PostLoadAssetRegistryTags(const FAssetData& InAssetData, TArray& OutTagsAndValuesToUpdate) const override; + virtual void PostLoadAssetRegistryTags(const FAssetData &InAssetData, TArray &OutTagsAndValuesToUpdate) const override; #endif }; diff --git a/spine-ue4/Plugins/SpinePlugin/Source/SpinePlugin/Public/SpineSkeletonDataAsset.h b/spine-ue4/Plugins/SpinePlugin/Source/SpinePlugin/Public/SpineSkeletonDataAsset.h index 407c521e9..af9ade5b0 100644 --- a/spine-ue4/Plugins/SpinePlugin/Source/SpinePlugin/Public/SpineSkeletonDataAsset.h +++ b/spine-ue4/Plugins/SpinePlugin/Source/SpinePlugin/Public/SpineSkeletonDataAsset.h @@ -116,7 +116,7 @@ protected: virtual void PostInitProperties() override; virtual void GetAssetRegistryTags(TArray &OutTags) const override; virtual void Serialize(FArchive &Ar) override; - virtual void PostLoadAssetRegistryTags(const FAssetData& InAssetData, TArray& OutTagsAndValuesToUpdate) const override; + virtual void PostLoadAssetRegistryTags(const FAssetData &InAssetData, TArray &OutTagsAndValuesToUpdate) const override; #endif void LoadInfo(); From d12431d72cb49f322d8c4812fe17377df2bde1b0 Mon Sep 17 00:00:00 2001 From: Mario Zechner Date: Tue, 24 Oct 2023 17:11:10 +0200 Subject: [PATCH 3/3] =?UTF-8?q?[haxe]=20Fix=20MeshAttachment#updateRegion?= =?UTF-8?q?=20for=20the=20270=C2=B0=20case.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- spine-haxe/spine-haxe/spine/attachments/MeshAttachment.hx | 1 + 1 file changed, 1 insertion(+) diff --git a/spine-haxe/spine-haxe/spine/attachments/MeshAttachment.hx b/spine-haxe/spine-haxe/spine/attachments/MeshAttachment.hx index d712f457d..5d91f0250 100644 --- a/spine-haxe/spine-haxe/spine/attachments/MeshAttachment.hx +++ b/spine-haxe/spine-haxe/spine/attachments/MeshAttachment.hx @@ -103,6 +103,7 @@ class MeshAttachment extends VertexAttachment implements HasTextureRegion { while (i < n) { uvs[i] = u + (1 - regionUVs[i + 1]) * width; uvs[i + 1] = v + regionUVs[i] * height; + i += 2; } return; }