diff --git a/api/python/Abstract/objects/pyParser.cpp b/api/python/Abstract/objects/pyParser.cpp index 1f67f20e14..fdd1180d8c 100644 --- a/api/python/Abstract/objects/pyParser.cpp +++ b/api/python/Abstract/objects/pyParser.cpp @@ -23,7 +23,20 @@ namespace LIEF { template<> void create(py::module& m) { - m.def("parse", + m.def("parse", + [] (py::bytes bytes, const std::string& name) { + std::string raw_str = bytes; + std::vector 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 (*) (const std::string&)>(&Parser::parse), "Parse the given binary and return a " RST_CLASS_REF(lief.Binary) " object", "filepath"_a, @@ -36,6 +49,7 @@ void create(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"); @@ -65,7 +79,8 @@ void create(py::module& m) { std::string raw_str = static_cast(rawio.attr("readall")()); std::vector 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); }, diff --git a/tests/api/test_python.py b/tests/api/test_python.py index d2758572ad..be89232a80 100644 --- a/tests/api/test_python.py +++ b/tests/api/test_python.py @@ -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): @@ -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__': @@ -52,4 +64,3 @@ def test_io(self): root_logger.addHandler(ch) unittest.main(verbosity=2) -