Skip to content

Commit a91c097

Browse files
committed
Majorly clean up InsertABCtoSWF logic
1 parent 4d21683 commit a91c097

File tree

1 file changed

+52
-58
lines changed

1 file changed

+52
-58
lines changed

Native/BytecodeEditor/source/ANEBytecodeEditorFunctions.cpp

Lines changed: 52 additions & 58 deletions
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,6 @@ FREObject InsertABCToSWF(FREContext, void*, uint32_t argc, FREObject argv[])
5858
DO_OR_FAIL("Failed to acquire SWF bytearray", FREAcquireByteArray(swf, &swfData));
5959
tags = SWF::SWFFile::getTagsFrom({swfData.bytes, swfLength});
6060

61-
static_assert(std::endian::native == std::endian::little);
6261
swfData.bytes[4] = uint8_t(finalSize);
6362
swfData.bytes[5] = uint8_t(finalSize >> 8);
6463
swfData.bytes[6] = uint8_t(finalSize >> 16);
@@ -67,101 +66,96 @@ FREObject InsertABCToSWF(FREContext, void*, uint32_t argc, FREObject argv[])
6766
FREByteArray abcData;
6867
DO_OR_FAIL("Failed to acquire ABC bytearray", FREAcquireByteArray(abc, &abcData));
6968

70-
size_t currentTag = 0;
71-
while (currentTag < tags.size() && tags[currentTag].type != TagType::DoABC2 &&
72-
tags[currentTag].type != TagType::End)
73-
{
74-
currentTag++;
75-
}
76-
77-
if (currentTag == tags.size())
69+
auto shiftTags = [&tags, &swfData](size_t currentTag, ptrdiff_t shiftBy,
70+
std::optional<TagType> excludeType = std::nullopt)
7871
{
79-
DO_OR_FAIL("Failed to release swf bytearray", FREReleaseByteArray(swf));
80-
DO_OR_FAIL("Failed to release abc bytearray", FREReleaseByteArray(abc));
81-
FAIL("No ABC or end tag in this SWF. Is it really an SWF?");
82-
}
72+
std::vector<ptrdiff_t> localOffsets(tags.size());
8373

84-
if (tags[currentTag].type == TagType::End)
85-
{
86-
std::copy(abcData.bytes, abcData.bytes + abcData.length,
87-
swfData.bytes + std::distance((const uint8_t*)swfData.bytes,
88-
getTagOrigStart(tags[currentTag])));
89-
90-
swfData.bytes[finalSize - 2] = 0;
91-
swfData.bytes[finalSize - 1] = 0;
92-
}
93-
else if (currentTag < tags.size() - 1)
94-
{
95-
std::vector<ptrdiff_t> localOffsets(tags.size() - currentTag - 1);
74+
// Get the offsets for all the tags we need to copy
75+
for (size_t i = currentTag; i < tags.size(); i++)
9676
{
97-
ptrdiff_t globalOffset = std::distance((const uint8_t*)swfData.bytes,
98-
getTagOrigStart(tags[currentTag])) +
99-
abcLength;
100-
101-
// Get the offsets for all the tags we need to copy
102-
for (size_t i = currentTag + 1; i < tags.size(); i++)
77+
localOffsets[i] = shiftBy;
78+
if (tags[i].type == excludeType)
10379
{
104-
localOffsets[i - currentTag - 1] =
105-
globalOffset -
106-
std::distance((const uint8_t*)swfData.bytes, getTagOrigStart(tags[i]));
107-
if (tags[i].type != TagType::DoABC2)
108-
{
109-
globalOffset += getTagTotalSize(tags[i]);
110-
}
80+
shiftBy -= getTagTotalSize(tags[i]);
11181
}
11282
}
11383

11484
// Then copy them, forwards if they go backwards and backwards if they go forwards
11585
// - This ensures that you don't copy copied data
116-
for (size_t i = 0; i < localOffsets.size(); i++)
86+
for (size_t i = currentTag; i < tags.size(); i++)
11787
{
118-
const auto& tag = tags[currentTag + 1 + i];
88+
auto& tag = tags[i];
11989
if (localOffsets[i] < 0)
12090
{
121-
if (tag.type != TagType::DoABC2)
91+
if (tag.type != excludeType)
12292
{
12393
tag.writeTo(
12494
swfData.bytes +
12595
std::distance((const uint8_t*)swfData.bytes, getTagOrigStart(tag)) +
12696
localOffsets[i]);
97+
tag.data += localOffsets[i];
12798
}
12899
}
129-
else
130-
{
131-
break;
132-
}
133100
}
134-
for (size_t i = localOffsets.size(); i > 0; i--)
101+
for (size_t i = tags.size(); i > currentTag; i--)
135102
{
136-
const auto& tag = tags[currentTag + 1 + i - 1];
103+
auto& tag = tags[i - 1];
137104
if (localOffsets[i - 1] > 0)
138105
{
139-
if (tag.type != TagType::DoABC2)
106+
if (tag.type != excludeType)
140107
{
141108
tag.writeToBackwards(
142109
swfData.bytes +
143110
std::distance((const uint8_t*)swfData.bytes, getTagOrigStart(tag)) +
144111
localOffsets[i - 1]);
112+
tag.data += localOffsets[i - 1];
145113
}
146114
}
147-
else
148-
{
149-
break;
150-
}
151115
}
116+
};
117+
118+
auto overwriteData = [&](FREByteArray copyIn, ptrdiff_t offset)
119+
{
120+
// And add the actual new data in
121+
std::copy(copyIn.bytes, copyIn.bytes + copyIn.length, swfData.bytes + offset);
122+
};
152123

153-
// And add the actual new ABC data in
154-
std::copy(abcData.bytes, abcData.bytes + abcLength,
155-
swfData.bytes + std::distance((const uint8_t*)swfData.bytes,
156-
getTagOrigStart(tags[currentTag])));
124+
bool doneABC = false;
125+
int doneSymbolClass = 0;
126+
127+
size_t currentTag = 0;
128+
while (currentTag < tags.size() && tags[currentTag].type != TagType::End)
129+
{
130+
if (!doneABC && tags[currentTag].type == TagType::DoABC2)
131+
{
132+
shiftTags(currentTag + 1,
133+
ptrdiff_t(abcLength) - ptrdiff_t(getTagTotalSize(tags[currentTag])),
134+
TagType::DoABC2);
135+
overwriteData(abcData, std::distance((const uint8_t*)swfData.bytes,
136+
getTagOrigStart(tags[currentTag])));
137+
doneABC = true;
138+
}
139+
currentTag++;
157140
}
158-
else
141+
142+
if (currentTag == tags.size())
159143
{
160144
DO_OR_FAIL("Failed to release swf bytearray", FREReleaseByteArray(swf));
161145
DO_OR_FAIL("Failed to release abc bytearray", FREReleaseByteArray(abc));
162-
FAIL("End tag is missing");
146+
FAIL("No end tag in this SWF. Is it really an SWF?");
163147
}
164148

149+
if (!doneABC)
150+
{
151+
DO_OR_FAIL("Failed to release swf bytearray", FREReleaseByteArray(swf));
152+
DO_OR_FAIL("Failed to release abc bytearray", FREReleaseByteArray(abc));
153+
FAIL("No ABC tag present in this SWF.");
154+
}
155+
156+
swfData.bytes[finalSize - 2] = 0;
157+
swfData.bytes[finalSize - 1] = 0;
158+
165159
DO_OR_FAIL("Failed to release swf bytearray", FREReleaseByteArray(swf));
166160
DO_OR_FAIL("Failed to release abc bytearray", FREReleaseByteArray(abc));
167161

0 commit comments

Comments
 (0)