Package: irssi
Version: 0.8.15-2
Severity: normal
Tags: patch

The Perl interface gets negative file size injected which leads to funny
behavior if the script relies on positve and advancing numbers.
The patch attached fixes the issue.

Sebastian
>From b01f3d0ffbfc211883349b19f52267f0d85d6423 Mon Sep 17 00:00:00 2001
From: Sebastian Andrzej Siewior <sebast...@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 <sebast...@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.5.4

Reply via email to