std::result. LIEF is using a std::expected-like to handle errors. Since this interface is only available in C++23, we rely on TartanLlama/expected which provides this interface for C++11/C++17.
Basically, LIEF functions that use this idiom return a LIEF::result
which wraps the effective result or an error.
The user can process this result as follows:
result<PE_TYPE> pe_type = PE::get_type("/tmp/NotPE.elf")
if (pe_type) {
PE_TYPE effective_type = pe_type.value();
} else {
lief_errors err = as_lief_err(pe_type);
}
In the case of Python, we leverage the dynamic features of the language to return either: the expected value or an error if the function failed. For instance, if we take the lief.PE.get_type()
function, the former implementation of this function raised an exception to inform the user:
try:
pe_type = lief.PE.get_type("/tmp/NotPE.elf")
# If it does not fail, pe_type handles a lief.PE.PE_TYPE object
except Exception as e:
print(f"Error: {e}")
With the new implementation that relies on the ResultOrError
idiom, the function returns the lief.PE.PE_TYPE
value is everything is ok and in the case of a processing error, it returns a lief.lief_errors
.
The user can handle this new interface by using the isinstance()
function or by comparing the value with a lief.lief_errors
attribute:
pe_type = lief.PE.get_type("/tmp/NotPE.elf")
if pe_type == lief.lief_errors.file_error:
print("File error")
elif isinstance(pe_type, lief.lief_errors):
print("Another kind of error")
else:
print("No error, type is: {}".format(pe_type))
Wrapper that contains an Object (T
) or an error.
The tl/expected implementation exposes the method value()
to access the underlying object (if no error)
Typical usage is:
result<int> intval = my_function();
if (intval) {
int val = intval.value();
} else { // There is an error
std::cout << get_error(intval).message() << "\n";
}
See https://tl.tartanllama.xyz/en/latest/api/expected.html for more details
Return the lief_errors when the provided result<T>
is an error.
LIEF error codes definition.
Values:
Opaque structure that is used by LIEF to avoid writing result<void> f(...)
. Instead, it makes the output explicit such as:
ok_error_t process() {
if (fail) {
return make_error_code(...);
}
return ok();
}
Return success for function with return type ok_error_t.
Opaque structure used by ok_error_t.
Bases: Enum
Enum class which represents an error generated by LIEF’s functions
Bases: object
Opaque value returned when a void function is executed successfully.
Bases: object
Return either: ok_t
(success) or lief_errors
(error)