From 91aea1572efe61b9467dff0b5508ec7ba88e8e3d Mon Sep 17 00:00:00 2001 From: Eelco Dolstra Date: Mon, 22 Aug 2022 14:09:52 +0200 Subject: [PATCH] Fix macOS build, where le32toh is not available --- src/libfetchers/zip-input-accessor.cc | 4 ++-- src/libutil/serialise.hh | 12 ++---------- src/libutil/util.hh | 11 +++++++++++ 3 files changed, 15 insertions(+), 12 deletions(-) diff --git a/src/libfetchers/zip-input-accessor.cc b/src/libfetchers/zip-input-accessor.cc index e391e5b71..7091e3664 100644 --- a/src/libfetchers/zip-input-accessor.cc +++ b/src/libfetchers/zip-input-accessor.cc @@ -1,7 +1,7 @@ #include "input-accessor.hh" #include -#include +#include namespace nix { @@ -61,7 +61,7 @@ struct ZipInputAccessor : InputAccessor zip_uint16_t id, len; auto extra = zip_file_extra_field_get(zipFile, i, 0, &id, &len, ZIP_FL_CENTRAL); if (id == 0x5455 && len >= 5) - lastModified = std::max(lastModified, (time_t) le32toh(*((uint32_t *) (extra + 1)))); + lastModified = std::max(lastModified, readLittleEndian((unsigned char *) extra + 1)); } auto slash = strchr(sb.name, '/'); diff --git a/src/libutil/serialise.hh b/src/libutil/serialise.hh index 84847835a..7da5b07fd 100644 --- a/src/libutil/serialise.hh +++ b/src/libutil/serialise.hh @@ -331,17 +331,9 @@ T readNum(Source & source) unsigned char buf[8]; source((char *) buf, sizeof(buf)); - uint64_t n = - ((uint64_t) buf[0]) | - ((uint64_t) buf[1] << 8) | - ((uint64_t) buf[2] << 16) | - ((uint64_t) buf[3] << 24) | - ((uint64_t) buf[4] << 32) | - ((uint64_t) buf[5] << 40) | - ((uint64_t) buf[6] << 48) | - ((uint64_t) buf[7] << 56); + auto n = readLittleEndian(buf); - if (n > (uint64_t)std::numeric_limits::max()) + if (n > (uint64_t) std::numeric_limits::max()) throw SerialisationError("serialised integer %d is too large for type '%s'", n, typeid(T).name()); return (T) n; diff --git a/src/libutil/util.hh b/src/libutil/util.hh index 5164c7f57..e6eb65017 100644 --- a/src/libutil/util.hh +++ b/src/libutil/util.hh @@ -506,6 +506,17 @@ std::optional string2Float(const std::string_view s) } +/* Convert a little-endian integer to host order. */ +template +T readLittleEndian(unsigned char * p) +{ + T x = 0; + for (size_t i = 0; i < sizeof(x); ++i) + x |= *p++ << (i * 8); + return x; +} + + /* Return true iff `s' starts with `prefix'. */ bool hasPrefix(std::string_view s, std::string_view prefix);