summaryrefslogtreecommitdiff
path: root/lib/libalpm/util.c
diff options
context:
space:
mode:
authorDan McGee <dan@archlinux.org>2011-08-29 12:12:54 -0500
committerDan McGee <dan@archlinux.org>2011-08-29 19:57:05 -0500
commit234b6ffc2c39268d1efdc414e02bc4b352e5d931 (patch)
treef01da20df830137e3954631e93a5ce698b310109 /lib/libalpm/util.c
parentd74dad79b7770725090e1eb2a015cbd6f88aed66 (diff)
downloadpacman-234b6ffc2c39268d1efdc414e02bc4b352e5d931.tar.xz
Parse > 2GiB file sizes correctly
We were using atol(), which on 32 bit, cannot handle values greater than 2GiB, which is fail. Switch to a strtoull() wrapper function tailored toward parsing off_t values. This allows parsing of very large positive integer values. off_t is a signed type, but in our usages, we never parse or have a need for negative values, so the function will return -1 on error. Before: $ pacman -Si flightgear-data | grep Size Download Size : 2097152.00 K Installed Size : 2097152.00 K After: $ ./src/pacman/pacman -Si flightgear-data | grep Size Download Size : 2312592.52 KiB Installed Size : 5402896.00 KiB Signed-off-by: Dan McGee <dan@archlinux.org>
Diffstat (limited to 'lib/libalpm/util.c')
-rw-r--r--lib/libalpm/util.c25
1 files changed, 25 insertions, 0 deletions
diff --git a/lib/libalpm/util.c b/lib/libalpm/util.c
index 98eaa175..4cb31a8a 100644
--- a/lib/libalpm/util.c
+++ b/lib/libalpm/util.c
@@ -1074,6 +1074,31 @@ unsigned long _alpm_hash_sdbm(const char *str)
return hash;
}
+off_t _alpm_strtoofft(const char *line)
+{
+ char *end;
+ unsigned long long result;
+ errno = 0;
+
+ /* we are trying to parse bare numbers only, no leading anything */
+ if(line[0] < '1' || line[0] > '9') {
+ return (off_t)-1;
+ }
+ result = strtoull(line, &end, 10);
+ if (result == 0 && end == line) {
+ /* line was not a number */
+ return (off_t)-1;
+ } else if (result == ULLONG_MAX && errno == ERANGE) {
+ /* line does not fit in unsigned long long */
+ return (off_t)-1;
+ } else if (*end) {
+ /* line began with a number but has junk left over at the end */
+ return (off_t)-1;
+ }
+
+ return (off_t)result;
+}
+
long _alpm_parsedate(const char *line)
{
if(isalpha((unsigned char)line[0])) {