Commit fa23579e authored by David Gonçalves's avatar David Gonçalves 📖

fix bug with exporting elf, fix bug with symbol name containing a trailing \0,...

fix bug with exporting elf, fix bug with symbol name containing a trailing \0, and add a new method that returns all the symbols ids and names
parent fb474dc8
Pipeline #219529694 passed with stages
in 4 minutes and 14 seconds
......@@ -35,7 +35,8 @@ map<int, string> SWF::tagTypeNames = {
{70, "PlaceObject3"}, {71, "Import2"}, {72, "DoABCDefine"}, {73, "DefineFontAlignZones"}, {74, "CSMTextSettings"},
{75, "DefineFont3"}, {76, "SymbolClass"}, {77, "Metadata"}, {78, "DefineScalingGrid"}, {82, "DoABC"}, {83, "DefineShape4"},
{84, "DefineMorphShape2"}, {86, "DefineSceneAndFrameData"}, {87, "DefineBinaryData"}, {88, "DefineFontName"},
{90, "DefineBitsJPEG4"}};
{89, "StartSound2"}, {90, "DefineBitsJPEG4"}, {91, "DefineFont4"}, {93, "EnableTelemetry"}, {94, "PlaceObject4"}
};
SWF::SWF(const std::vector<uint8_t> &buffer) : tags(), version(),
frameSize(), frameRate(), frameCount(), projector() {
......@@ -45,19 +46,21 @@ SWF::SWF(const std::vector<uint8_t> &buffer) : tags(), version(),
/**
* Export SWF as EXE. The binary file is as follows:
* Windows:
* 1. Projector binary
* 2. SWF binary
* 3. Footer 0xFA123456 (little endian)
* 4. SWF binary length
* Linux:
* 1. Projector binary
* 2. SWF binary length
* 3. Footer 0xFA123456 (little endian)
* 4. SWF binary
*
* Compression:
* 0 - uncompressed
* 1 - zlib
* 2 - lzma
*
* TO-DO:
* - Make function detect if projector is Windows executable or Linux ELF,
* and change write order accordingly.
*/
vector<uint8_t> SWF::exportExe(const std::vector<uint8_t> &proj, int compression) {
......@@ -90,21 +93,22 @@ vector<uint8_t> SWF::exportExe(const std::vector<uint8_t> &proj, int compression
throw swf_exception("No projector file given.");
}
// 1st comes projector
concatVectorWithContainer(bytes, this->projector.buffer, false);
if (this->projector.windows) {
// 1st comes projector
concatVectorWithContainer(bytes, this->projector.buffer, false);
// 2nd comes swf (aka original 'bytes')
// 3rd comes projector footer
concatVectorWithContainer(bytes, this->projector.footer);
// 4th comes swf length
concatVectorWithContainer(bytes, length);
} else {
// 1st comes projector
// 2nd comes swf length
concatVectorWithContainer(bytes, length, false);
// 3rd comes projector footer
// 4th comes swf (aka original 'bytes')
concatVectorWithContainer(bytes, this->projector.footer, false);
concatVectorWithContainer(bytes, length, false);
concatVectorWithContainer(bytes, this->projector.buffer, false);
}
return bytes;
......@@ -270,11 +274,14 @@ void SWF::parseSwf(const std::vector<uint8_t> &buffer) {
cur += 2;
string name;
while (true) {
name += static_cast<char>(swfBuf[++cur]);
if (swfBuf[cur] == 0)
++cur;
if (swfBuf[cur] == 0) {
break;
}
name += static_cast<char>(swfBuf[cur]);
}
sc->symbolClass.emplace_back(pair<size_t, string>(tid, name));
//SWF_DEBUG(tid << " - " << name);
}
// Add tag to vector of tags
......@@ -342,7 +349,9 @@ size_t SWF::parseSwfHeader(std::vector<uint8_t> &buffer) {
this->frameSize.emplace_back(static_cast<char>(buffer[cur++]));
}
#ifdef SWF_DEBUG_BUILD
debugFrameSize(this->frameSize, nbits);
#endif
this->frameRate = {buffer[cur], buffer[++cur]}; // bytes 17, 18
......@@ -357,7 +366,6 @@ size_t SWF::parseSwfHeader(std::vector<uint8_t> &buffer) {
}
void SWF::debugFrameSize(const vector<uint8_t> &fs, size_t nbits) {
#ifdef SWF_DEBUG_BUILD
size_t frameSizeBits = nbits * 4 + 5;
// frameSizeBits must be a multiple of 8
......@@ -389,7 +397,6 @@ void SWF::debugFrameSize(const vector<uint8_t> &fs, size_t nbits) {
SWF_DEBUG("\tXmax: " << xMax << " twips (" << twipsToPx(xMax) << " px)");
SWF_DEBUG("\tYmin: " << yMin << " twips (" << twipsToPx(yMin) << " px)");
SWF_DEBUG("\tYmax: " << yMax << " twips (" << twipsToPx(yMax) << " px)");
#endif
}
vector<Tag *> SWF::getTagsOfType(int type) {
......@@ -411,19 +418,25 @@ Tag * SWF::getTagWithId(size_t id) {
return nullptr;
}
string SWF::getSymbolName(size_t id) const {
for (auto &t : this->tags) {
std::vector< std::pair<size_t, std::string> > SWF::getAllSymbols() const {
std::vector< std::pair<size_t, std::string> > symbols;
for (auto const &t : this->tags) {
if (t->type == tagId("SymbolClass")) {
Tag_SymbolClass *sc = static_cast<Tag_SymbolClass *>(t.get());
auto *sc = static_cast<Tag_SymbolClass *>(t.get());
concatVectorWithContainer(symbols, sc->symbolClass);
}
}
return symbols;
}
string SWF::getSymbolName(size_t id) const {
for (auto const &t : this->tags) {
if (t->type == tagId("SymbolClass")) {
auto *sc = static_cast<Tag_SymbolClass *>(t.get());
auto it = find_if(sc->symbolClass.begin(), sc->symbolClass.end(),
[id](const std::pair<size_t, std::string> &p) -> bool { return p.first == id; });
[id](const std::pair<size_t, std::string> &p) -> bool { return p.first == id; });
if (it != sc->symbolClass.end()) {
string name = it->second;
if (name.back() == 0) {
name.pop_back();
}
return name;
return it->second;
}
}
}
......
......@@ -73,6 +73,7 @@ namespace swf {
void replaceBinary(const std::vector<uint8_t> &binBuf, size_t tagId);
inline bool hasProjector() { return ! projector.buffer.empty(); }
inline bool isProjectorWindows() { return projector.windows; }
std::vector< std::pair<size_t, std::string> > getAllSymbols() const;
std::string getSymbolName(size_t id) const;
private:
void parseSwf(const std::vector<uint8_t> &buffer);
......
......@@ -95,6 +95,7 @@ vector<uint8_t> Tag_SymbolClass::toBytes() const {
array<uint8_t, 2> tid = dectobytes_le<uint16_t>( static_cast<uint16_t>(p.first) );
content.insert(content.end(), tid.begin(), tid.end());
content.insert(content.end(), p.second.begin(), p.second.end());
content.emplace_back(0);
}
array<uint8_t, 4> len = dectobytes_le<uint32_t>(static_cast<uint32_t>(content.size()) + 2); // numSymbols
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment