express: better fix for encrypt_string Python 3 issues

A workaround for the bug described in #684 was made in e080d33e31 but this fix is significantly cleaner.

Unit test was added.
This commit is contained in:
rdb
2019-07-10 13:46:42 +02:00
parent b2d327f268
commit fa62344452
4 changed files with 30 additions and 24 deletions

View File

@@ -6408,21 +6408,9 @@ pack_return_value(ostream &out, int indent_level, FunctionRemap *remap,
TypeManager::is_vector_unsigned_char(type)) {
// Most types are now handled by the many overloads of Dtool_WrapValue,
// defined in py_panda.h.
if (!remap->_has_this && remap->_cppfunc != nullptr &&
remap->_cppfunc->get_simple_name() == "encrypt_string" &&
return_expr == "return_value") {
// Temporary hack to fix #684 to avoid an ABI change.
out << "#if PY_MAJOR_VERSION >= 3\n";
indent(out, indent_level)
<< "return PyBytes_FromStringAndSize((char *)return_value.data(), (Py_ssize_t)return_value.size());\n";
out << "#else\n";
indent(out, indent_level)
<< "return PyString_FromStringAndSize((char *)return_value.data(), (Py_ssize_t)return_value.size());\n";
out << "#endif\n";
} else {
indent(out, indent_level)
<< "return Dtool_WrapValue(" << return_expr << ");\n";
}
indent(out, indent_level)
<< "return Dtool_WrapValue(" << return_expr << ");\n";
} else if (TypeManager::is_pointer(type)) {
bool is_const = TypeManager::is_const_pointer_to_anything(type);
bool owns_memory = remap->_return_value_needs_management;

View File

@@ -17,6 +17,7 @@
#include "encryptStream.h"
#include "virtualFileSystem.h"
#include "config_express.h"
#include "stringStream.h"
using std::istream;
using std::istringstream;
@@ -26,12 +27,12 @@ using std::string;
/**
* Encrypts the indicated source string using the given password, and the
* algorithm specified by encryption-algorithm. Returns the encrypted string.
* algorithm specified by encryption-algorithm. Returns the encrypted data.
*/
string
vector_uchar
encrypt_string(const string &source, const string &password,
const string &algorithm, int key_length, int iteration_count) {
ostringstream dest;
StringStream dest;
{
OEncryptStream encrypt;
@@ -48,11 +49,13 @@ encrypt_string(const string &source, const string &password,
encrypt.write(source.data(), source.length());
if (encrypt.fail()) {
return string();
return vector_uchar();
}
}
return dest.str();
vector_uchar result;
dest.swap_data(result);
return result;
}
/**
@@ -64,8 +67,8 @@ encrypt_string(const string &source, const string &password,
* easily be detected, and the return value may simply be a garbage string.
*/
string
decrypt_string(const string &source, const string &password) {
istringstream source_stream(source);
decrypt_string(const vector_uchar &source, const string &password) {
StringStream source_stream(source);
ostringstream dest_stream;
if (!decrypt_stream(source_stream, dest_stream, password)) {

View File

@@ -19,15 +19,16 @@
#ifdef HAVE_OPENSSL
#include "filename.h"
#include "vector_uchar.h"
BEGIN_PUBLISH
EXPCL_PANDA_EXPRESS std::string
EXPCL_PANDA_EXPRESS vector_uchar
encrypt_string(const std::string &source, const std::string &password,
const std::string &algorithm = std::string(), int key_length = -1,
int iteration_count = -1);
EXPCL_PANDA_EXPRESS std::string
decrypt_string(const std::string &source, const std::string &password);
decrypt_string(const vector_uchar &source, const std::string &password);
EXPCL_PANDA_EXPRESS bool
encrypt_file(const Filename &source, const Filename &dest, const std::string &password,

View File

@@ -0,0 +1,14 @@
from panda3d import core
def test_encrypt_string():
# Test encrypt and then decrypt cycle
enc = core.encrypt_string('abcdefg', '12345')
assert len(enc) > 0
dec = core.decrypt_string(enc, '12345')
assert dec == 'abcdefg'
# Test pre-encrypted string
enc = b'[\x00\x10\x00d\x00\xb5\x7f\xc44Y\xb7\xd9\x15\xe3\xbd\xcf\xb3yK\xfb\xf6'
assert 'test' == core.decrypt_string(enc, '98765')