FIX: Lzma plugin - range check errors

This commit is contained in:
Alexander Koblov 2011-12-13 10:35:10 +00:00
commit 59a16c8ce1
6 changed files with 30 additions and 36 deletions

View file

@ -20,12 +20,13 @@ type TBFSMode=(BFMRead,BFMWrite);
bufferdirty:boolean;
Mode:TBFSMode;
procedure Init;
procedure Flush;
procedure ReadBuffer;
public
constructor Create(const FileName: string; Mode: Word); overload;
constructor Create(const FileName: string; Mode: Word; Rights: Cardinal); overload;
destructor Destroy; override;
procedure Flush;
function Read(var Buffer; Count: Longint): Longint; override;
function Write(const Buffer; Count: Longint): Longint; override;
function Seek(const Offset: Int64; Origin: TSeekOrigin): Int64; override;
@ -60,20 +61,20 @@ end;
constructor TBufferedFS.Create(const FileName: string; Mode: Word);
begin
inherited;
inherited Create(FileName, Mode);
init;
end;
constructor TBufferedFS.Create(const FileName: string; Mode: Word; Rights: Cardinal);
begin
inherited;
inherited Create(FileName, Mode, Rights);
init;
end;
destructor TBufferedFS.Destroy;
begin
flush;
inherited;
inherited Destroy;
end;
procedure TBufferedFS.ReadBuffer;

View file

@ -150,7 +150,7 @@ symbol := 1;
repeat
symbol := (symbol shl 1) or rangeDecoder.DecodeBit(m_Decoders, symbol);
until not (symbol < $100);
result:=symbol;
result:= byte(symbol);
end;
function TLZMADecoder2.DecodeWithMatchByte(const rangeDecoder:TRangeDecoder;matchByte:byte):byte;
@ -161,7 +161,7 @@ begin
symbol := 1;
repeat
matchBit := (matchByte shr 7) and 1;
matchByte := matchByte shl 1;
matchByte := byte(matchByte shl 1);
bit := rangeDecoder.DecodeBit(m_Decoders, ((1 + matchBit) shl 8) + symbol);
symbol := (symbol shl 1) or bit;
if (matchBit <> bit) then begin
@ -171,7 +171,7 @@ repeat
break;
end;
until not (symbol < $100);
result:=symbol;
result:= byte(symbol);
end;
procedure TLZMALiteralDecoder._Create(const numPosBits, numPrevBits:integer);

View file

@ -1171,7 +1171,7 @@ var i:integer;
begin
properties[0] := (_posStateBits * 5 + _numLiteralPosStateBits) * 9 + _numLiteralContextBits;
for i := 0 to 3 do
properties[1 + i] := (_dictionarySize shr (8 * i));
properties[1 + i] := byte(_dictionarySize shr (8 * i));
outStream.write(properties, kPropSize);
end;

View file

@ -54,8 +54,8 @@ begin
result:=0;
for i := numTotalBits downto 1 do begin
range:=range shr 1;
t := ((Code - Range) shr 31);
Code := Code - Range and (t - 1);
t := (cardinal(Code - Range) shr 31);
Code := integer(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);
@ -68,7 +68,7 @@ function TRangeDecoder.DecodeBit(var probs: array of smallint;const index:intege
var prob,newbound:integer;
begin
prob:=probs[index];
newbound:=(Range shr kNumBitModelTotalBits) * prob;
newbound:= integer((Range shr kNumBitModelTotalBits) * prob);
if (integer((integer(Code) xor integer($80000000))) < integer((integer(newBound) xor integer($80000000)))) then begin
Range := newBound;
probs[index] := (prob + ((kBitModelTotal - prob) shr kNumMoveBits));
@ -78,8 +78,8 @@ if (integer((integer(Code) xor integer($80000000))) < integer((integer(newBound)
end;
result:=0;
end else begin
Range := Range - newBound;
Code := Code - newBound;
Range := integer(Range - newBound);
Code := integer(Code - newBound);
probs[index] := (prob - ((prob) shr kNumMoveBits));
if ((Range and kTopMask) = 0) then begin
Code := (Code shl 8) or ReadByte(stream);

View file

@ -83,7 +83,7 @@ if (LowHi <> 0) or (Low < int64($FF000000)) then begin
position := position + cacheSize;
temp := cache;
repeat
WriteByte(stream,temp + LowHi);
WriteByte(stream,byte(temp + LowHi));
temp := $FF;
dec(cacheSize);
until(cacheSize = 0);
@ -123,13 +123,13 @@ procedure TRangeEncoder.Encode(var probs: array of smallint;const index,symbol:i
var prob,newbound:integer;
begin
prob := probs[index];
newBound := (Range shr kNumBitModelTotalBits) * prob;
newBound := integer((Range shr kNumBitModelTotalBits) * prob);
if (symbol = 0) then begin
Range := newBound;
probs[index] := (prob + ((kBitModelTotal - prob) shr kNumMoveBits));
end else begin
Low := Low + (newBound and int64($FFFFFFFF));
Range := Range - newBound;
Range := integer(Range - newBound);
probs[index] := (prob - ((prob) shr kNumMoveBits));
end;
if ((Range and kTopMask) = 0) then begin

View file

@ -85,9 +85,6 @@ type
{ TLzmaHandle }
function TLzmaHandle.Open(const FileName: String): LongInt;
var
I: Integer;
v: Byte;
begin
Result:= E_SUCCESS;
try
@ -100,13 +97,9 @@ begin
if Result <> E_SUCCESS then Exit;
if inStream.Read(Properties, PropertiesSize) <> PropertiesSize then
Exit(E_BAD_DATA);
outSize:= 0;
for I:= 0 to 7 do begin
v:= {shortint}(ReadByte(inStream));
if v < 0 then
Exit(E_EREAD);
outSize := outSize or v shl (8 * I);
end;
outSize := LEtoN(inStream.ReadQWord);
if (outSize = DWORD(-1)) then
outSize := 0;
end;
destructor TLzmaHandle.Destroy;
@ -277,7 +270,6 @@ var
outStream: TBufferedFS = nil;
encoder: TLZMAEncoder = nil;
filesize: Int64;
I: Integer;
sInputFileName: String;
begin
Result:= E_SUCCESS;
@ -318,16 +310,17 @@ begin
else
fileSize:= inStream.Size;
end;
for I:= 0 to 7 do
WriteByte(outStream, (fileSize shr (8 * I)) and $FF);
outStream.WriteQWord(NtoLE(fileSize));
encoder.Code(inStream, outStream, -1, -1);
finally
if Assigned(encoder) then
FreeAndNil(encoder);
if Assigned(outStream) then
FreeAndNil(outStream);
if Assigned(inStream) then
FreeAndNil(inStream);
FreeAndNil(encoder);
{$IFDEF CPU64}
outStream.Flush;
FileClose(outStream.Handle);
{$ELSE}
FreeAndNil(outStream);
{$ENDIF}
FreeAndNil(inStream);
end;
end;
@ -347,4 +340,4 @@ begin
end;
end;
end.
end.