Skip to content

Commit

Permalink
Fix Python parsing with input 'bytes'
Browse files Browse the repository at this point in the history
  • Loading branch information
rthomas committed Nov 28, 2019
1 parent ca4e614 commit b0e480c
Show file tree
Hide file tree
Showing 2 changed files with 45 additions and 19 deletions.
19 changes: 17 additions & 2 deletions api/python/Abstract/objects/pyParser.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,20 @@ namespace LIEF {
template<>
void create<Parser>(py::module& m) {

m.def("parse",
m.def("parse",
[] (py::bytes bytes, const std::string& name) {
std::string raw_str = bytes;
std::vector<uint8_t> raw = {
std::make_move_iterator(std::begin(raw_str)),
std::make_move_iterator(std::end(raw_str))
};
return Parser::parse(std::move(raw), name);
},
"Parse the given binary and return a " RST_CLASS_REF(lief.Binary) " object",
"raw"_a, "name"_a = "",
py::return_value_policy::take_ownership);

m.def("parse",
static_cast<std::unique_ptr<Binary> (*) (const std::string&)>(&Parser::parse),
"Parse the given binary and return a " RST_CLASS_REF(lief.Binary) " object",
"filepath"_a,
Expand All @@ -36,6 +49,7 @@ void create<Parser>(py::module& m) {
py::return_value_policy::take_ownership);



m.def("parse",
[] (py::object byteio, const std::string& name) {
auto&& io = py::module::import("io");
Expand Down Expand Up @@ -65,7 +79,8 @@ void create<Parser>(py::module& m) {
std::string raw_str = static_cast<py::bytes>(rawio.attr("readall")());
std::vector<uint8_t> raw = {
std::make_move_iterator(std::begin(raw_str)),
std::make_move_iterator(std::end(raw_str))};
std::make_move_iterator(std::end(raw_str))
};

return Parser::parse(std::move(raw), name);
},
Expand Down
45 changes: 28 additions & 17 deletions tests/api/test_python.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,14 @@
import unittest
import lief
import logging
from io import open
import io
from io import open as io_open
from unittest import TestCase
from utils import get_sample

from lief import Logger
Logger.set_level(lief.LOGGING_LEVEL.WARNING)

from unittest import TestCase
from utils import get_sample

class TestPythonApi(TestCase):

def setUp(self):
Expand All @@ -18,28 +18,40 @@ def setUp(self):
def test_io(self):
lspath = get_sample('ELF/ELF64_x86-64_binary_ls.bin')

with open(lspath, 'r') as f:
ls = lief.parse(f);
self.assertIsNotNone(ls.abstract.header)

ls = lief.parse(lspath)
self.assertIsNotNone(ls.abstract.header)

with open(lspath, 'rb') as f:
ls = lief.parse(f);
with io_open(lspath, 'r') as f:
ls = lief.parse(f)
self.assertIsNotNone(ls.abstract.header)

with io_open(lspath, 'rb') as f:
ls = lief.parse(f)
self.assertIsNotNone(ls.abstract.header)

with open(lspath, 'rb') as f:
ls = lief.ELF.parse(f);
with io_open(lspath, 'rb') as f:
ls = lief.ELF.parse(f)
self.assertIsNotNone(ls.abstract.header)

with open(get_sample('PE/PE64_x86-64_binary_HelloWorld.exe'), 'rb') as f:
binary = lief.PE.parse(f);
with io_open(get_sample('PE/PE64_x86-64_binary_HelloWorld.exe'), 'rb') as f:
binary = lief.PE.parse(f)
self.assertIsNotNone(binary.abstract.header)

with open(get_sample('MachO/MachO64_x86-64_binary_dd.bin'), 'rb') as f:
binary = lief.MachO.parse(f)[0];
with io_open(get_sample('MachO/MachO64_x86-64_binary_dd.bin'), 'rb') as f:
binary = lief.MachO.parse(f)[0]
self.assertIsNotNone(binary.abstract.header)

with open(lspath, 'rb') as f: # As bytes
ls = lief.parse(f.read())
self.assertIsNotNone(ls.abstract.header)

with open(lspath, 'rb') as f: # As io.BufferedReader
ls = lief.parse(f)
self.assertIsNotNone(ls.abstract.header)

with open(lspath, 'rb') as f: # As io.BytesIO object
bytes_stream = io.BytesIO(f.read())
self.assertIsNotNone(bytes_stream)


if __name__ == '__main__':
Expand All @@ -52,4 +64,3 @@ def test_io(self):
root_logger.addHandler(ch)

unittest.main(verbosity=2)

0 comments on commit b0e480c

Please sign in to comment.