New version

- Beware of unsigned long int on 32bit arches (#1333149) (vpodzime)
This commit is contained in:
Vratislav Podzimek 2016-05-06 10:34:49 +02:00
parent 804a401f20
commit cd064fcccc
2 changed files with 125 additions and 1 deletions

View File

@ -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 <vpodzime@redhat.com> - 0.6-2
- Beware of unsigned long int on 32bit arches (#1333149) (vpodzime)
* Tue May 03 2016 Vratislav Podzimek <vpodzime@redhat.com> - 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)

118
uli_32bit.patch Normal file
View File

@ -0,0 +1,118 @@
From d2f78ba3782534f2a2719fdbda20275f6c40c073 Mon Sep 17 00:00:00 2001
From: Vratislav Podzimek <vpodzime@redhat.com>
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 <vpodzime@redhat.com>
---
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 <langinfo.h>
#include <stdarg.h>
#include <stdio.h>
+#include <inttypes.h>
#include <string.h>
#include <ctype.h>
#include <pcre.h>
@@ -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