irssi-import / bugs.irssi.org

bugs.irssi.org archive
https://github.com/irssi/irssi/issues
0 stars 0 forks source link

DCC transfer size in scripts is negative for file size > 2GiB #872

Open irssibot opened 11 years ago

irssibot commented 11 years ago

Using newSViv() makes numbers >2GiB negative because it translate the number into an signed integer.

The file attached fixes the issue.

irssibot commented 11 years ago

0001-perl-use-newSVpv-for-dcc-s-file-size-fields.patch

From 1ad7297a4fa4839171e76f6658e14d1a56dc38d1 Mon Sep 17 00:00:00 2001
From: Sebastian Andrzej Siewior <sebastian@breakpoint.cc>
Date: Sun, 7 Aug 2011 19:42:18 +0200
Subject: [PATCH] perl: use newSVpv for dcc's file size fields

Using newSViv() makes numbers >2GiB negative because it translate the number
into an signed integer. This patch use a tiny trick by converting the number
into a string. Once perl starts using this numbers for computation in
translates them into a 32bit (unsigned) integer or a 64bit one. Been testing
with a 5GiB file and it seems to do the job.
This changes the transfd (transfer bytes), size (total file size) and skipped
(skipped bytes uppon transfer) members.

Signed-off-by: Sebastian Andrzej Siewior <sebastian@breakpoint.cc>
---
 src/common.h        |    3 +++
 src/perl/irc/Irc.xs |   13 ++++++++++---
 2 files changed, 13 insertions(+), 3 deletions(-)

diff --git a/src/common.h b/src/common.h
index bb24696..7cb84b7 100644
--- a/src/common.h
+++ b/src/common.h
@@ -58,10 +58,13 @@

 #if defined (UOFF_T_INT)
 typedef unsigned int uoff_t;
+#define uoff_t_printf "%u"
 #elif defined (UOFF_T_LONG)
 typedef unsigned long uoff_t;
+#define uoff_t_printf "%lu"
 #elif defined (UOFF_T_LONG_LONG)
 typedef unsigned long long uoff_t;
+#define uoff_t_printf "%llu"
 #else
 #  error uoff_t size not set
 #endif
diff --git a/src/perl/irc/Irc.xs b/src/perl/irc/Irc.xs
index 251efb8..5b0da51 100644
--- a/src/perl/irc/Irc.xs
+++ b/src/perl/irc/Irc.xs
@@ -36,6 +36,8 @@ static void perl_ban_fill_hash(HV *hv, BAN_REC *ban)

 static void perl_dcc_fill_hash(HV *hv, DCC_REC *dcc)
 {
+   char fsize[22];
+
    hv_store(hv, "type", 4, new_pv(dcc_type2str(dcc->type)), 0);
    hv_store(hv, "orig_type", 9, new_pv(dcc_type2str(dcc->orig_type)), 0);
    hv_store(hv, "created", 7, newSViv(dcc->created), 0);
@@ -53,7 +55,8 @@ static void perl_dcc_fill_hash(HV *hv, DCC_REC *dcc)
    hv_store(hv, "port", 4, newSViv(dcc->port), 0);

    hv_store(hv, "starttime", 9, newSViv(dcc->starttime), 0);
-   hv_store(hv, "transfd", 7, newSViv(dcc->transfd), 0);
+   snprintf(fsize, sizeof(fsize), uoff_t_printf, dcc->transfd);
+   hv_store(hv, "transfd", 7, newSVpv(fsize, 0), 0);
 }

 static void perl_dcc_chat_fill_hash(HV *hv, CHAT_DCC_REC *dcc)
@@ -67,10 +70,14 @@ static void perl_dcc_chat_fill_hash(HV *hv, CHAT_DCC_REC *dcc)

 static void perl_dcc_file_fill_hash(HV *hv, FILE_DCC_REC *dcc)
 {
+   char fsize[22];
+
         perl_dcc_fill_hash(hv, (DCC_REC *) dcc);

-   hv_store(hv, "size", 4, newSViv(dcc->size), 0);
-   hv_store(hv, "skipped", 7, newSViv(dcc->skipped), 0);
+   snprintf(fsize, sizeof(fsize), uoff_t_printf, dcc->size);
+   hv_store(hv, "size", 4, newSVpv(fsize, 0), 0);
+   snprintf(fsize, sizeof(fsize), uoff_t_printf, dcc->skipped);
+   hv_store(hv, "skipped", 7, newSVpv(fsize, 0), 0);
 }

 static void perl_dcc_get_fill_hash(HV *hv, GET_DCC_REC *dcc)
-- 
1.7.10.4