[fpc-pascal] LZMA Algorithm fails on 64bit

JoshyFun joshyfun at gmail.com
Tue Jan 26 00:09:18 CET 2010


Hello FPC-Pascal,

Monday, January 25, 2010, 7:14:05 PM, you wrote:

>> I hope to have some spare time this afternoon to test it, as I also
>> need LZMA decompress in 64 bit.
MK> I checked it: Decompressing files on 64bit-machines which were compressed
MK> on 32bit-linux does not work. Which means:
MK>  32bit-compressed -> 32bit-decompression ==> Works!
MK>  64bit-compressed -> 64bit-decompression ==> Does not work
MK>  64bit-compressed -> 32bit-decompression ==> Works!
MK>  32bit-compressed -> 64bit-decompression ==> Does not work.

Found the bug in URangeDecoder.pas

function TRangeDecoder.DecodeDirectBits(const numTotalBits:integer):integer;
var i,t:integer;
begin
result:=0;
for i := numTotalBits downto 1 do begin
    range:=range shr 1;
    //Old Code:
    //t := ((Code - Range) shr 31);
    //New one:
    t := (DWORD(Code - Range) shr 31);
    Code := Code - Range and (t - 1);
    result := (result shl 1) or (1 - t);
    if ((Range and kTopMask) = 0) then begin
       Code := (Code shl 8) or ReadByte(stream);
       Range := Range shl 8;
       end;
    end;
end;

DWORD fixes the problem, as:

32 bits: ($80000001 - 1) shr 31 = 1
64 bits: ($80000001 - 1) shr 31 = -1
64 bits: DWORD($80000001 - 1) shr 31 = -1

It looks like a problem in 64 bit versions :-? I think this topic
appears in the past about 32<->64 bits shift operations over signed
variables.

-- 
Best regards,
 JoshyFun




More information about the fpc-pascal mailing list