summaryrefslogtreecommitdiff
path: root/pp_pack.c
diff options
context:
space:
mode:
authorNicholas Clark <nick@ccl4.org>2002-10-08 22:52:53 +0100
committerhv <hv@crypt.org>2002-10-12 15:31:06 +0000
commit0258719bae4c02bba26598151f1f335a54f43190 (patch)
treeef4daa815993b2559aa81888345fb50c8c2a14aa /pp_pack.c
parentb3c1f772f352b72296ce50a1ba2e7abcc581baaa (diff)
downloadperl-0258719bae4c02bba26598151f1f335a54f43190.tar.gz
Re: [perl #17772] pack "w" /* this cannot happen ;-) */ is fallacious
Message-ID: <20021008205253.GA283@Bagpuss.unfortu.net> p4raw-id: //depot/perl@18010
Diffstat (limited to 'pp_pack.c')
-rw-r--r--pp_pack.c18
1 files changed, 14 insertions, 4 deletions
diff --git a/pp_pack.c b/pp_pack.c
index 486c4f7136..44764541df 100644
--- a/pp_pack.c
+++ b/pp_pack.c
@@ -2286,7 +2286,7 @@ Perl_pack_cat(pTHX_ SV *cat, char *pat, register char *patend, register SV **beg
/* Copy string and check for compliance */
from = SvPV(fromstr, len);
if ((norm = is_an_int(from, len)) == NULL)
- Perl_croak(aTHX_ "can compress only unsigned integer");
+ Perl_croak(aTHX_ "Can only compress unsigned integers");
New('w', result, len, char);
in = result + len;
@@ -2299,15 +2299,25 @@ Perl_pack_cat(pTHX_ SV *cat, char *pat, register char *patend, register SV **beg
SvREFCNT_dec(norm); /* free norm */
}
else if (SvNOKp(fromstr)) {
- char buf[sizeof(NV) * 2]; /* 8/7 <= 2 */
+ /* 10**NV_MAX_10_EXP is the largest power of 10
+ so 10**(NV_MAX_10_EXP+1) is definately unrepresentable
+ given 10**(NV_MAX_10_EXP+1) == 128 ** x solve for x:
+ x = (NV_MAX_10_EXP+1) * log (10) / log (128)
+ And with that many bytes only Inf can overflow.
+ */
+#ifdef NV_MAX_10_EXP
+ char buf[1 + (int)((NV_MAX_10_EXP + 1) * 0.47456)];
+#else
+ char buf[1 + (int)((308 + 1) * 0.47456)];
+#endif
char *in = buf + sizeof(buf);
anv = Perl_floor(anv);
do {
NV next = Perl_floor(anv / 128);
- *--in = (unsigned char)(anv - (next * 128)) | 0x80;
if (in <= buf) /* this cannot happen ;-) */
Perl_croak(aTHX_ "Cannot compress integer");
+ *--in = (unsigned char)(anv - (next * 128)) | 0x80;
anv = next;
} while (anv > 0);
buf[sizeof(buf) - 1] &= 0x7f; /* clear continue bit */
@@ -2322,7 +2332,7 @@ Perl_pack_cat(pTHX_ SV *cat, char *pat, register char *patend, register SV **beg
/* Copy string and check for compliance */
from = SvPV(fromstr, len);
if ((norm = is_an_int(from, len)) == NULL)
- Perl_croak(aTHX_ "can compress only unsigned integer");
+ Perl_croak(aTHX_ "Can only compress unsigned integers");
New('w', result, len, char);
in = result + len;