4
0
mirror of https://github.com/QuasarApp/LIEF.git synced 2025-05-07 01:09:33 +00:00

Handle python utf-16 conversion in LangCodeItem values

This commit is contained in:
rthomas 2020-11-17 18:18:48 +01:00
parent d2218e549d
commit 44e072da15
6 changed files with 29 additions and 21 deletions
api/python/PE/objects/resources
doc/sphinx
include/LIEF/PE/resources
src/PE/resources
tests/pe

@ -74,8 +74,14 @@ void create<LangCodeItem>(py::module& m) {
"" RST_CLASS_REF(lief.PE.CODE_PAGES) " for which :attr:`~lief.PE.LangCodeItem.items` are defined")
.def_property("items",
static_cast<std::map<std::u16string, std::u16string>& (LangCodeItem::*)(void)>(&LangCodeItem::items),
static_cast<setter_t<const std::map<std::u16string, std::u16string>&>>(&LangCodeItem::items))
[] (const LangCodeItem& item) -> py::dict {
py::dict output;
for (const auto& p : item.items()) {
output[u16tou8(p.first).c_str()] = py::bytes(u16tou8(p.second));
}
return output;
},
static_cast<setter_t<const LangCodeItem::items_t&>>(&LangCodeItem::items))
.def("__eq__", &LangCodeItem::operator==)

@ -18,6 +18,8 @@ Changelog
* Bug fix in the symbols table reconstruction (ELF)
:PE:
* :attr:`~lief.PE.LangCodeItem.items` now returns a dictionary whose values are **bytes** (instead of
``str`` object). This change is related to ``utf-16`` support.
* :github_user:`kohnakagawa` fixed wrong enums values: :commit:`c03125045e32a9cd65c613585eb4d0385350c6d2`, :commit:`6ee808a1e4611d09c6cf0aea82a612be69584db9`, :commit:`cd05f34bae681fc8af4b5e7cc28eaef816802b6f`
* :github_user:`kohnakagawa` fixed a bug in the PE resources parser (:commit:`a7254d1ba935783f16effbc7faddf993c57e82f7`)
* Handle PE forwarded exports (`issues/307 <https://github.com/lief-project/LIEF/issues/307>`_)

@ -18,7 +18,7 @@
#include <iostream>
#include <sstream>
#include <vector>
#include <map>
#include <unordered_map>
#include "LIEF/visibility.h"
@ -41,6 +41,7 @@ class LIEF_API LangCodeItem : public Object {
friend class ResourcesManager;
public:
using items_t = std::unordered_map<std::u16string, std::u16string>;
LangCodeItem(void);
LangCodeItem(const LangCodeItem&);
@ -69,8 +70,8 @@ class LIEF_API LangCodeItem : public Object {
//! @brief Sublang for which @link LangCodeItem::items items @endlink are defined
RESOURCE_SUBLANGS sublang(void) const;
const std::map<std::u16string, std::u16string>& items(void) const;
std::map<std::u16string, std::u16string>& items(void);
const items_t& items(void) const;
items_t& items(void);
void type(uint16_t type);
void key(const std::u16string& key);
@ -80,7 +81,7 @@ class LIEF_API LangCodeItem : public Object {
void lang(RESOURCE_LANGS lang);
void sublang(RESOURCE_SUBLANGS lang);
void items(const std::map<std::u16string, std::u16string>& items);
void items(const items_t& items);
virtual void accept(Visitor& visitor) const override;
@ -93,8 +94,7 @@ class LIEF_API LangCodeItem : public Object {
private:
uint16_t type_;
std::u16string key_;
std::map<std::u16string, std::u16string> items_;
items_t items_;
};

@ -32,7 +32,7 @@ namespace PE {
class ResourcesManager;
class ResourceVersion;
//! @brief Modelization of the ``StringFileInfo`` structure
//! @brief Modelization of the ``StringFileInfo`` structure
//!
//! It contains version information that can be displayed for a particular language and code page.
//!

@ -78,12 +78,12 @@ RESOURCE_SUBLANGS LangCodeItem::sublang(void) const {
}
const std::map<std::u16string, std::u16string>& LangCodeItem::items(void) const {
const LangCodeItem::items_t& LangCodeItem::items(void) const {
return this->items_;
}
std::map<std::u16string, std::u16string>& LangCodeItem::items(void) {
return const_cast<std::map<std::u16string, std::u16string>&>(static_cast<const LangCodeItem*>(this)->items());
LangCodeItem::items_t& LangCodeItem::items(void) {
return const_cast<LangCodeItem::items_t&>(static_cast<const LangCodeItem*>(this)->items());
}
@ -145,7 +145,7 @@ void LangCodeItem::sublang(RESOURCE_SUBLANGS lang) {
}
void LangCodeItem::items(const std::map<std::u16string, std::u16string>& items) {
void LangCodeItem::items(const LangCodeItem::items_t& items) {
this->items_ = items;
}
@ -176,7 +176,7 @@ std::ostream& operator<<(std::ostream& os, const LangCodeItem& item) {
<< " - "
<< std::hex << to_string(item.code_page()) << ")" << std::endl;
os << std::setw(8) << std::setfill(' ') << "Items: " << std::endl;
for (const std::pair<const std::u16string, std::u16string>& p : item.items()) {
for (const LangCodeItem::items_t::value_type& p : item.items()) {
os << " " << "'" << u16tou8(p.first) << "': '" << u16tou8(p.second) << "'" << std::endl;
}
return os;

@ -157,28 +157,28 @@ class TestResource(TestCase):
if sys.version_info < (3,):
self.assertEqual(items['CompanyName'].encode("utf8"), 'TODO: <Nom de la société>')
else:
self.assertEqual(items['CompanyName'], 'TODO: <Nom de la société>')
self.assertEqual(items['CompanyName'], b'TODO: <Nom de la soci\xc3\xa9t\xc3\xa9>')
self.assertIn('FileVersion', items)
self.assertEqual(items['FileVersion'], '1.0.0.1')
self.assertEqual(items['FileVersion'], b'1.0.0.1')
self.assertIn('InternalName', items)
self.assertEqual(items['InternalName'], 'Hello.exe')
self.assertEqual(items['InternalName'], b'Hello.exe')
self.assertIn('LegalCopyright', items)
if sys.version_info < (3,):
self.assertEqual(items['LegalCopyright'].encode("utf8"), 'TODO: (c) <Nom de la société>. Tous droits réservés.')
else:
self.assertEqual(items['LegalCopyright'], 'TODO: (c) <Nom de la société>. Tous droits réservés.')
self.assertEqual(items['LegalCopyright'].decode("utf8"), 'TODO: (c) <Nom de la société>. Tous droits réservés.')
self.assertIn('OriginalFilename', items)
self.assertEqual(items['OriginalFilename'], 'Hello.exe')
self.assertEqual(items['OriginalFilename'], b'Hello.exe')
self.assertIn('ProductName', items)
self.assertEqual(items['ProductName'], 'TODO: <Nom du produit>')
self.assertEqual(items['ProductName'], b'TODO: <Nom du produit>')
self.assertIn('ProductVersion', items)
self.assertEqual(items['ProductVersion'], '1.0.0.1')
self.assertEqual(items['ProductVersion'], b'1.0.0.1')
# Check ResourceVarFileInfo
self.assertEqual(var_file_info.type, 1)