-=| Jonathan Yu, Mon, Feb 08, 2010 at 07:47:16PM -0500 |=- > I'm hesitant to apply gregoa's patch because it seems like it might > have problems where machines *cannot* left-shift 62 bits... If the > register is only 32-bits wide (as with i386 on older machines), then > this may result in data falling off the end (and $low4bytes will be > zeroed out). > > I think we can look into something with the Config module, which will > tell us various info that perl -V tells us, such as: > intsize=4, longsize=8, ptrsize=8, doublesize=8, byteorder=12345678
Here's what perlop(1) has to say: Note that both "<<" and ">>" in Perl are implemented directly using "<<" and ">>" in C. If "use integer" (see "Integer Arithmetic") is in force then signed C integers are used, else unsigned C integers are used. Either way, the implementation isn't going to generate results larger than the size of the integer type Perl was built with (32 bits or 64 bits). The result of overflowing the range of the integers is undefined because it is undefined also in C. In other words, using 32-bit integers, "1 << 32" is undefined. Shifting by a negative number of bits is also undefined. Funnily, the variable is called $low4bytes, which implies that it intented to contain 64bit integers, no mater what the processor. This is not right, because 64-bit arithmetic doesn't work with 32-bit integers: # on 32-bit Celeron $ perl -MConfig -w <<'EOF' print "$Config{intsize}\n"; print "$Config{longsize}\n"; print "$Config{ptrsize}\n"; print 1<<60, "\n"; print 1<<28, "\n"; EOF 4 4 4 268435456 268435456 # on 64-bit Phenom 4 8 8 1152921504606846976 268435456 How about forwarding the bugreport upstream? Or reading some description of MPEG and figuring out what the code really does… To me the right fix seems to be to treat the "low 4 bytes" as an array of four bytes, instead of one 64-bit integer. Using Bit::Vector or Math::BigInt may also be an option.
signature.asc
Description: Digital signature