diff --git a/libbytesize.spec b/libbytesize.spec index 6d97c80..fbff4d2 100644 --- a/libbytesize.spec +++ b/libbytesize.spec @@ -1,6 +1,6 @@ Name: libbytesize Version: 0.6 -Release: 1%{?dist} +Release: 2%{?dist} Summary: A library for working with sizes in bytes License: LGPLv2+ URL: https://github.com/rhinstaller/libbytesize @@ -8,6 +8,8 @@ Source0: https://github.com/rhinstaller/libbytesize/archive/%{name}-%{versio %define realname bytesize +Patch0: uli_32bit.patch + BuildRequires: gmp-devel BuildRequires: mpfr-devel BuildRequires: pcre-devel @@ -51,6 +53,7 @@ the library from Python 3 easier and more convenient. %prep %setup -q -n %{name}-%{version} +%patch0 -p1 %build %configure @@ -87,6 +90,9 @@ find %{buildroot} -type f -name "*.la" | xargs %{__rm} %{python3_sitearch}/bytesize/__pycache__/* %changelog +* Fri May 6 2016 Vratislav Podzimek - 0.6-2 +- Beware of unsigned long int on 32bit arches (#1333149) (vpodzime) + * Tue May 03 2016 Vratislav Podzimek - 0.6-1 - Add support for the ROUND_HALF_UP rounding mode (vpodzime) - Make sure we return the right radix char in human_readable() (vpodzime) diff --git a/uli_32bit.patch b/uli_32bit.patch new file mode 100644 index 0000000..541c98b --- /dev/null +++ b/uli_32bit.patch @@ -0,0 +1,118 @@ +From d2f78ba3782534f2a2719fdbda20275f6c40c073 Mon Sep 17 00:00:00 2001 +From: Vratislav Podzimek +Date: Thu, 5 May 2016 15:20:43 +0200 +Subject: [PATCH] Beware of unsigned long int on 32bit arches (#1333149) + +GMP has no function to assign an mpz_t instance from usigned long long int and +unsigned long int may be just a 32bit number on some architectures. So let's +just convert the number we get into a string and use the initializer from string +instead. + +Signed-off-by: Vratislav Podzimek +--- + src/bs_size.c | 38 +++++++++++++++++++++++++++++++++++--- + src/bs_size.h | 1 + + tests/libbytesize_unittest.py | 6 ++++++ + 3 files changed, 42 insertions(+), 3 deletions(-) + +diff --git a/src/bs_size.c b/src/bs_size.c +index 71d7b48..8c55678 100644 +--- a/src/bs_size.c ++++ b/src/bs_size.c +@@ -3,6 +3,7 @@ + #include + #include + #include ++#include + #include + #include + #include +@@ -329,8 +330,16 @@ BSSize bs_size_new (void) { + * Returns: a new #BSSize + */ + BSSize bs_size_new_from_bytes (uint64_t bytes, int sgn) { ++ char *num_str = NULL; + BSSize ret = bs_size_new (); +- mpz_set_ui (ret->bytes, bytes); ++ int ok = 0; ++ ++ ok = asprintf (&num_str, "%"PRIu64, bytes); ++ if (ok == -1) ++ /* probably cannot allocate memory, there's nothing more we can do */ ++ return ret; ++ mpz_set_str (ret->bytes, num_str, 10); ++ free (num_str); + if (sgn == -1) + mpz_neg (ret->bytes, ret->bytes); + return ret; +@@ -475,13 +484,36 @@ BSSize bs_size_new_from_size (const BSSize size) { + * Returns: the @size in a number of bytes + */ + uint64_t bs_size_get_bytes (const BSSize size, int *sgn, BSError **error) { +- if (mpz_cmp_ui (size->bytes, UINT64_MAX) > 0) { ++ char *num_str = NULL; ++ mpz_t max; ++ uint64_t ret = 0; ++ int ok = 0; ++ ++ mpz_init2 (max, (mp_bitcnt_t) 64); ++ ok = asprintf (&num_str, "%"PRIu64, UINT64_MAX); ++ if (ok == -1) { ++ /* we probably cannot allocate memory so we are doomed */ ++ set_error (error, BS_ERROR_FAIL, strdup("Failed to allocate memory")); ++ mpz_clear (max); ++ return 0; ++ } ++ mpz_set_str (max, num_str, 10); ++ free (num_str); ++ if (mpz_cmp (size->bytes, max) > 0) { + set_error (error, BS_ERROR_OVER, strdup("The size is too big, cannot be returned as a 64bit number of bytes")); + return 0; + } ++ mpz_clear (max); + if (sgn) + *sgn = mpz_sgn (size->bytes); +- return (uint64_t) mpz_get_ui (size->bytes); ++ if (mpz_cmp_ui (size->bytes, UINT64_MAX) <= 0) ++ return (uint64_t) mpz_get_ui (size->bytes); ++ else { ++ num_str = bs_size_get_bytes_str (size); ++ ret = strtoull (num_str, NULL, 10); ++ free (num_str); ++ return ret; ++ } + } + + /** +diff --git a/src/bs_size.h b/src/bs_size.h +index 0a961df..e7e29c6 100644 +--- a/src/bs_size.h ++++ b/src/bs_size.h +@@ -24,6 +24,7 @@ typedef enum { + BS_ERROR_INVALID_SPEC, + BS_ERROR_OVER, + BS_ERROR_ZERO_DIV, ++ BS_ERROR_FAIL + } BSErrorCode; + + /** +diff --git a/tests/libbytesize_unittest.py b/tests/libbytesize_unittest.py +index ce4b01d..e57dc0b 100755 +--- a/tests/libbytesize_unittest.py ++++ b/tests/libbytesize_unittest.py +@@ -123,6 +123,12 @@ class SizeTestCase(unittest.TestCase): + actual = SizeStruct.new_from_bytes(1024, -1).get_bytes() + expected = (1024, -1) + self.assertEqual(actual, expected) ++ ++ # now let's try something bigger than MAXUINT32 ++ actual = SizeStruct.new_from_bytes(5718360*1024, 1).get_bytes() ++ expected = (5718360*1024, 1) ++ self.assertEqual(actual, expected) ++ + #enddef + + def testNewFromSizeStruct(self): +-- +2.5.5 +