diff options
author | Nuno Goncalves <[email protected]> | 2019-10-09 23:26:13 +0200 |
---|---|---|
committer | Nuno Goncalves <[email protected]> | 2019-10-14 18:04:37 +0200 |
commit | 760419ef719721fd8ee8d7d8bb77d27bd66801fa (patch) | |
tree | 49b70ef8510469cd233e53e0d3ea43dc4eba2131 | |
parent | 241bf6d3d5205aa4a3d05a3a079207d6d2b27d87 (diff) |
roughtime: decode integer values properly also on big endian arch (fix #2137)
Signed-off-by: Nuno Goncalves <[email protected]>
-rw-r--r-- | src/lib/misc/roughtime/roughtime.cpp | 32 |
1 files changed, 30 insertions, 2 deletions
diff --git a/src/lib/misc/roughtime/roughtime.cpp b/src/lib/misc/roughtime/roughtime.cpp index c9767546a..94a9a6b82 100644 --- a/src/lib/misc/roughtime/roughtime.cpp +++ b/src/lib/misc/roughtime/roughtime.cpp @@ -21,6 +21,34 @@ namespace Botan { namespace { +template< bool B, class T = void > +using enable_if_t = typename std::enable_if<B,T>::type; + +template<class T> +struct is_array : std::false_type {}; + +template<class T, std::size_t N> +struct is_array<std::array<T,N>>:std::true_type{}; + +template<typename T> +T from_little_endian(const uint8_t* t, size_t N = sizeof(T)) + { + static_assert(sizeof(T)<=sizeof(int64_t),""); + return (N == 0) ? T(0) : (T(static_cast<int64_t>(t[N-1]) << ((N-1)*8)) + from_little_endian<T>(t,N-1)); + } + +template<typename T, enable_if_t<is_array<T>::value>* = nullptr> +T copy(const uint8_t* t) + { + return typecast_copy<T>(t); //arrays are endianess indepedent, so we do a memcpy + } + +template<typename T, enable_if_t<!is_array<T>::value>* = nullptr> +T copy(const uint8_t* t) + { + return from_little_endian<T>(t); //other types are arithmetic, so we account that roughtime serializes as little endian + } + template<typename T> std::map<std::string, std::vector<uint8_t>> unpack_roughtime_packet(T bytes) { @@ -35,7 +63,7 @@ std::map<std::string, std::vector<uint8_t>> unpack_roughtime_packet(T bytes) std::map<std::string, std::vector<uint8_t>> tags; for(uint32_t i=0; i<num_tags; ++i) { - const uint32_t end = ((i+1) == num_tags) ? bytes.size() : start_content + typecast_copy<uint32_t>(buf + 4 + i*4); + const uint32_t end = ((i+1) == num_tags) ? bytes.size() : start_content + from_little_endian<uint32_t>(buf + 4 + i*4); if(end > bytes.size()) { throw Roughtime::Roughtime_Error("Tag end index out of bounds"); } if(end < start) @@ -58,7 +86,7 @@ T get(const std::map<std::string, std::vector<uint8_t>>& map, const std::string& { throw Roughtime::Roughtime_Error("Tag " + label + " not found"); } if(tag->second.size() != sizeof(T)) { throw Roughtime::Roughtime_Error("Tag " + label + " has unexpected size"); } - return typecast_copy<T>(tag->second.data()); + return copy<T>(tag->second.data()); } const std::vector<uint8_t>& get_v(const std::map<std::string, std::vector<uint8_t>>& map, const std::string& label) |