summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTony Cook <tony@develop-help.com>2012-03-24 00:27:52 +0100
committerTony Cook <tony@develop-help.com>2012-03-24 03:02:22 +0100
commit4dd9a80bfc60f1266dd827fe2a22e375f7deb06e (patch)
treee40eddc3e28c6956ac0c6dd95cc74e6b1b35a1b8
parent3259dda591d8c770ec2d6eac9b182cfa16ef82af (diff)
downloadperl-tonyc/vec64.tar.gz
[rt #111730] don't use I32 for offsets in vec()tonyc/vec64
do_vecset() do_vecget() used I32 for the offset, which meant that offsets outside the -2Gb - +2Gb offset were truncated, resulting in various misbehaviours. size is still an I32 in each case, but that's limited to small numbers - powers of 2 from 1 to a current maximum of 64, so I didn't see much value to changing that.
-rw-r--r--doop.c4
-rw-r--r--embed.fnc2
-rw-r--r--proto.h2
-rw-r--r--t/bigmem/vec.t4
4 files changed, 5 insertions, 7 deletions
diff --git a/doop.c b/doop.c
index f1304772c2..cac9e1a26b 100644
--- a/doop.c
+++ b/doop.c
@@ -760,7 +760,7 @@ Perl_do_sprintf(pTHX_ SV *sv, I32 len, SV **sarg)
/* currently converts input to bytes if possible, but doesn't sweat failure */
UV
-Perl_do_vecget(pTHX_ SV *sv, I32 offset, I32 size)
+Perl_do_vecget(pTHX_ SV *sv, SSize_t offset, I32 size)
{
dVAR;
STRLEN srclen, len, uoffset, bitoffs = 0;
@@ -908,7 +908,7 @@ void
Perl_do_vecset(pTHX_ SV *sv)
{
dVAR;
- register I32 offset, bitoffs = 0;
+ register SSize_t offset, bitoffs = 0;
register I32 size;
register unsigned char *s;
register UV lval;
diff --git a/embed.fnc b/embed.fnc
index 8e3527d5e4..a7f7dc3402 100644
--- a/embed.fnc
+++ b/embed.fnc
@@ -379,7 +379,7 @@ pR |Off_t |do_tell |NN GV* gv
: Defined in doop.c, used only in pp.c
p |I32 |do_trans |NN SV* sv
: Used in my.c and pp.c
-p |UV |do_vecget |NN SV* sv|I32 offset|I32 size
+p |UV |do_vecget |NN SV* sv|SSize_t offset|I32 size
: Defined in doop.c, used only in mg.c (with /* XXX slurp this routine */)
p |void |do_vecset |NN SV* sv
: Defined in doop.c, used only in pp.c
diff --git a/proto.h b/proto.h
index 781719be63..e43c4370ec 100644
--- a/proto.h
+++ b/proto.h
@@ -893,7 +893,7 @@ PERL_CALLCONV I32 Perl_do_trans(pTHX_ SV* sv)
#define PERL_ARGS_ASSERT_DO_TRANS \
assert(sv)
-PERL_CALLCONV UV Perl_do_vecget(pTHX_ SV* sv, I32 offset, I32 size)
+PERL_CALLCONV UV Perl_do_vecget(pTHX_ SV* sv, SSize_t offset, I32 size)
__attribute__nonnull__(pTHX_1);
#define PERL_ARGS_ASSERT_DO_VECGET \
assert(sv)
diff --git a/t/bigmem/vec.t b/t/bigmem/vec.t
index ccdbb9bc43..bf3c513f63 100644
--- a/t/bigmem/vec.t
+++ b/t/bigmem/vec.t
@@ -16,12 +16,11 @@ $Config{ptrsize} >= 8
plan(7);
# RT #111730: Negative offset to vec in lvalue context
-local $::TODO = "RT #111730 - vec uses I32 for offsets";
my $v = "";
ok(scalar eval { vec($v, 0x80000000, 1) = 1 }, "set a bit at a large offset");
ok(vec($v, 0x80000000, 1), "check a bit at a large offset");
-{ local $::TODO; # succeeds but shouldn't at this point
+
ok(scalar eval { vec($v, 0x100000000, 1) = 1 },
"set a bit at a larger offset");
ok(vec($v, 0x100000000, 1), "check a bit at a larger offset");
@@ -29,7 +28,6 @@ ok(vec($v, 0x100000000, 1), "check a bit at a larger offset");
# real out of range values
ok(!eval { vec($v, -0x80000000, 1) = 1 },
"shouldn't be able to set at a large negative offset");
-}
ok(!eval { vec($v, -0x100000000, 1) = 1 },
"shouldn't be able to set at a larger negative offset");