Spelt / ZXing.Delphi

ZXing Barcode Scanning object Pascal Library for Delphi VCL and Delphi Firemonkey
Apache License 2.0
471 stars 206 forks source link

Segmentation fault (11) in function TBitMatrix.getBit #129

Closed macc2010 closed 2 years ago

macc2010 commented 2 years ago

Hello,

I have a Delphi FMX application running in Android and I get segmentation fault in function TBitMatrix.getBit.

My environment is Delphi 10.4 update 2 and I am using last sources from ZXing.Delphi.

Looking at the Call stack, the line where the fault happen is this :

bits := Fbits[offset];

So in order to avoid this segmentation fault, I have done the following change to the local copy of my source code :

function TBitMatrix.getBit(x, y: Integer): Boolean;
var
   offset, v, bits, shift: Int64;
   uBits: Cardinal;
begin
   offset := y * FrowSize + TMathUtils.Asr(x, 5);
   try
     if ( offset >= Low( FBits ) ) and ( offset <= High( FBits ) ) then
     begin
        bits := Fbits[offset];
        uBits := Cardinal(bits);
        shift := (x and $1F);
        v := TMathUtils.Asr(uBits, shift);
        Result := (v and 1) <> 0;
     end
     else
        Result := False;
   except
      Result := false;
   end;
end;
Spelt commented 2 years ago

Which version of Delphi do you use?

Op 31 mrt. 2022 om 15:12 heeft macc2010 @.***> het volgende geschreven:

 Hello,

I have a Delphi FMX application running in Android and I get segmentation fault in function TBitMatrix.getBit.

My environment is Delphi 10.4 update 2 and I am using last sources from ZXing.Delphi.

Looking at the Call stack, the line where the fault happen is this :

bits := Fbits[offset];

So in order to avoid this segmentation fault, I have done the following change to the local copy of my source code :

function TBitMatrix.getBit(x, y: Integer): Boolean; var offset, v, bits, shift: Int64; uBits: Cardinal; begin offset := y * FrowSize + TMathUtils.Asr(x, 5); try if ( offset >= Low( FBits ) ) and ( offset <= High( FBits ) ) then begin bits := Fbits[offset]; uBits := Cardinal(bits); shift := (x and $1F); v := TMathUtils.Asr(uBits, shift); Result := (v and 1) <> 0; end else Result := False; except Result := false; end; end;

— Reply to this email directly, view it on GitHub, or unsubscribe. You are receiving this because you are subscribed to this thread.

Spelt commented 2 years ago

Oops. You mentioned it already.

Op 31 mrt. 2022 om 15:12 heeft macc2010 @.***> het volgende geschreven:

 Hello,

I have a Delphi FMX application running in Android and I get segmentation fault in function TBitMatrix.getBit.

My environment is Delphi 10.4 update 2 and I am using last sources from ZXing.Delphi.

Looking at the Call stack, the line where the fault happen is this :

bits := Fbits[offset];

So in order to avoid this segmentation fault, I have done the following change to the local copy of my source code :

function TBitMatrix.getBit(x, y: Integer): Boolean; var offset, v, bits, shift: Int64; uBits: Cardinal; begin offset := y * FrowSize + TMathUtils.Asr(x, 5); try if ( offset >= Low( FBits ) ) and ( offset <= High( FBits ) ) then begin bits := Fbits[offset]; uBits := Cardinal(bits); shift := (x and $1F); v := TMathUtils.Asr(uBits, shift); Result := (v and 1) <> 0; end else Result := False; except Result := false; end; end;

— Reply to this email directly, view it on GitHub, or unsubscribe. You are receiving this because you are subscribed to this thread.

macc2010 commented 2 years ago

The QR code that I am reading is a base64 encoded data. I tell you if this is important for tests, anyway, I think that when a value is going to be assigned to an array, and the index of the array could be out of bounds ( because of that you have the except and Result := False ), it should be necessary to control the index of the array as I have done.

Thank you.

macc2010 commented 2 years ago

I think that if we would take control of the out of bounds, the try except would no longer be necessary.

Perhaps a code like this :


function TBitMatrix.getBit(x, y: Integer): Boolean;
var
   offset, v, bits, shift: Int64;
   uBits: Cardinal;
begin
   offset := y * FrowSize + TMathUtils.Asr(x, 5);
   if ( offset >= Low( FBits ) ) and ( offset <= High( FBits ) ) then
   begin
      bits := Fbits[offset];
      uBits := Cardinal(bits);
      shift := (x and $1F);
      v := TMathUtils.Asr(uBits, shift);
      Result := (v and 1) <> 0;
   end
   else
      Result := False;
end;
Spelt commented 2 years ago

Can you supply a photo of the QRCode ? So I can add it to the unit tests.

Op 1 apr. 2022 om 12:45 heeft macc2010 @.***> het volgende geschreven:

 I think that if we would take control of the out of bounds, the try except would no longer be necessary.

Perhaps a code like this :

function TBitMatrix.getBit(x, y: Integer): Boolean; var offset, v, bits, shift: Int64; uBits: Cardinal; begin offset := y * FrowSize + TMathUtils.Asr(x, 5); if ( offset >= Low( FBits ) ) and ( offset <= High( FBits ) ) then begin bits := Fbits[offset]; uBits := Cardinal(bits); shift := (x and $1F); v := TMathUtils.Asr(uBits, shift); Result := (v and 1) <> 0; end else Result := False; end; — Reply to this email directly, view it on GitHub, or unsubscribe. You are receiving this because you commented.

Spelt commented 2 years ago

Fix is in the next release.