Skip to content
Open
17 changes: 17 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -5,3 +5,20 @@
*.kdev4
/.kdev4
__pycache__
/bytes
/CMake*
/Debug
/.vs
ALL_BUILD*
*.vcxproj
*.filter
*.filters
*.recipe
*.log
*.tlog
*.obj
*.exe
*.pdb
*.txt
*.ilk
*.sln
24 changes: 19 additions & 5 deletions ASTree.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1218,7 +1218,15 @@ PycRef<ASTNode> BuildFromCode(PycRef<PycCode> code, PycModule* mod)
}
break;
}

// should check if stack_history has any item,if empty ,that count be a `junkcode-absjump`
if (!stack_hist.size()) {
// reset to next byte of JUMP_ABS
for (int i = 0; i < 4; i++) {
pos++;
source.getByte();
}
break;
}
stack = stack_hist.top();
stack_hist.pop();

Expand Down Expand Up @@ -2808,10 +2816,16 @@ void print_src(PycRef<ASTNode> node, PycModule* mod, std::ostream& pyc_output)
auto map = new ASTMap;
for (const auto& key : keys) {
// Values are pushed onto the stack in reverse order.
PycRef<ASTNode> value = values.back();
values.pop_back();
if (values.size() > 0) {
PycRef<ASTNode> value = values.back();
values.pop_back();
map->add(new ASTObject(key), value);
}
else {
map->add(new ASTObject(key), PycRef<ASTNode>());
}

map->add(new ASTObject(key), value);

}

print_src(map, mod, pyc_output);
Expand Down Expand Up @@ -3341,7 +3355,7 @@ void decompyle(PycRef<PycCode> code, PycModule* mod, std::ostream& pyc_output)
clean->removeFirst();
}
}
if (clean->nodes().back().type() == ASTNode::NODE_RETURN) {
if (clean->nodes().size() && clean->nodes().back().type() == ASTNode::NODE_RETURN) {
PycRef<ASTReturn> ret = clean->nodes().back().cast<ASTReturn>();

if (ret->value() == NULL || ret->value().type() == ASTNode::NODE_LOCALS) {
Expand Down
74 changes: 38 additions & 36 deletions pyc_string.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2,58 +2,60 @@
#include "pyc_module.h"
#include "data.h"
#include <stdexcept>
#include <wchar.h>

static bool check_ascii(const std::string& data)
{
auto cp = reinterpret_cast<const unsigned char*>(data.c_str());
while (*cp) {
if (*cp & 0x80)
return false;
++cp;
}
return true;
auto cp = reinterpret_cast<const unsigned char*>(data.c_str());
while (*cp) {
if (*cp & 0x80)
return false;
++cp;
}
return true;
}

/* PycString */
void PycString::load(PycData* stream, PycModule* mod)
{
if (type() == TYPE_STRINGREF) {
PycRef<PycString> str = mod->getIntern(stream->get32());
m_type = str->m_type;
m_value = str->m_value;
} else {
int length;
if (type() == TYPE_SHORT_ASCII || type() == TYPE_SHORT_ASCII_INTERNED)
length = stream->getByte();
else
length = stream->get32();
if (type() == TYPE_STRINGREF) {
PycRef<PycString> str = mod->getIntern(stream->get32());
m_type = str->m_type;
m_value = str->m_value;
}
else {
int length;
if (type() == TYPE_SHORT_ASCII || type() == TYPE_SHORT_ASCII_INTERNED)
length = stream->getByte();
else
length = stream->get32();

if (length < 0)
throw std::bad_alloc();
if (length < 0)
throw std::bad_alloc();

m_value.resize(length);
if (length) {
stream->getBuffer(length, &m_value.front());
if (type() == TYPE_ASCII || type() == TYPE_ASCII_INTERNED ||
type() == TYPE_SHORT_ASCII || type() == TYPE_SHORT_ASCII_INTERNED) {
if (!check_ascii(m_value))
throw std::runtime_error("Invalid bytes in ASCII string");
}
}
m_value.resize(length);
if (length) {
stream->getBuffer(length, &m_value.front());
if (type() == TYPE_ASCII || type() == TYPE_ASCII_INTERNED ||
type() == TYPE_SHORT_ASCII || type() == TYPE_SHORT_ASCII_INTERNED) {
if (!check_ascii(m_value))
throw std::runtime_error("Invalid bytes in ASCII string");
}
}

if (type() == TYPE_INTERNED || type() == TYPE_ASCII_INTERNED ||
type() == TYPE_SHORT_ASCII_INTERNED)
mod->intern(this);
}
if (type() == TYPE_INTERNED || type() == TYPE_ASCII_INTERNED ||
type() == TYPE_SHORT_ASCII_INTERNED)
mod->intern(this);
}
}

bool PycString::isEqual(PycRef<PycObject> obj) const
{
if (type() != obj.type())
return false;
if (type() != obj.type())
return false;

PycRef<PycString> strObj = obj.cast<PycString>();
return isEqual(strObj->m_value);
PycRef<PycString> strObj = obj.cast<PycString>();
return isEqual(strObj->m_value);
}

void PycString::print(std::ostream &pyc_output, PycModule* mod, bool triple,
Expand Down
2 changes: 1 addition & 1 deletion pycdc.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -89,7 +89,7 @@ int main(int argc, char* argv[])
}
const char* dispname = strrchr(infile, PATHSEP);
dispname = (dispname == NULL) ? infile : dispname + 1;
*pyc_output << "# Source Generated with Decompyle++\n";
*pyc_output << "# Source Generated with Decompyle++ , apply in pydumpck\n";
formatted_print(*pyc_output, "# File: %s (Python %d.%d%s)\n\n", dispname,
mod.majorVer(), mod.minorVer(),
(mod.majorVer() < 3 && mod.isUnicode()) ? " Unicode" : "");
Expand Down