Jump to content
Steve Maughan

D11.3 Surfaces a Bug in 8-Year-Old Code that reads DBF file...

Recommended Posts

I recently updated to D11.3 for AlignMix, our mapping solution. We were previously using D11.1. We have old code that reads a DBF file. This is used to read the DBF files associated with ESRI Shapefiles that contain geographic data. The code had worked for eight years without a problem. It still works in 32 bit mode but now doesn't work in 64 bit mode and gives an error. The DBF reading routine contains code that casts blocks of memory as strings etc — this is probably the root of the problem.

 

If anyone is interested, I've attached a sample project that reads a DBF file using the code.

 

In the sample project I only get two warnings:

 

[dcc32 Warning] uDBF.pas(155): W1000 Symbol 'StrPas' is deprecated: 'Moved to the AnsiStrings unit'

[dcc32 Warning] uDBF.pas(216): W1057 Implicit string cast from 'AnsiString' to 'string'

 

Are these relevant?

 

Question: what changed between D11.1 and D11.3 that could cause this type of problem? Was there any change involving casting of strings in 64 bit mode?

 

All help appreciated!

 

Steve

DBF-64-Bit-Bug.zip

Share this post


Link to post

"Data" is not initialized in your demo

 

GetMem(Data, iRecordLen);

 

and that's it, it ponts to trash

Share this post


Link to post
21 minutes ago, Attila Kovacs said:

"Data" is not initialized in your demo

 

GetMem(Data, iRecordLen);

 

and that's it, it ponts to trash

Thanks Attila, but I didn't think "Data" needed to be initialized. The GetMem function is asking the OS to allocate some memory of length "iRecord", and sets "Data" to point to the start of the allocated memory. Is this not correct?

 

— Steve  

Share this post


Link to post
Posted (edited)
7 minutes ago, Steve Maughan said:

Thanks Attila, but I didn't think "Data" needed to be initialized. The GetMem function is asking the OS to allocate some memory of length "iRecord", and sets "Data" to point to the start of the allocated memory. Is this not correct? 

 

— Steve  

Yes, but then you set up the fields' FData to point to there +iTmp and later you are trying to read the data from there, and AV raises.

But if I'm wrong just ignore me, I had only a minute to look into it.

 

Edited by Attila Kovacs
  • Like 1

Share this post


Link to post

 

    FData : DWORD;

And should be 8 bytes on 64 bit. Something like PAnsiChar.

        Fields^[iFieldCount].FData := DWORD(Data + iTmp);

It is wrong to cast to DWORD for 64 bit.

  • Like 1

Share this post


Link to post

@Cristian Peța you found it!! When I disable the ASLR in Delphi 11.3 it also runs fine in 64 bit mode. That makes sense.  MANY THANKS!

 

Now the question is, how do I make it work with ASLR enabled.

 

— Steve

 

 

Share this post


Link to post
Posted (edited)

I used FieldData array to store offsets instead of FData that must remain 4 bytes.

Maybe there are better approaches but it was faster so.

This is a fast patch and not optimal.

 

uDBF.pas

Edited by Cristian Peța
  • Like 1

Share this post


Link to post

Hi Cristian — many thanks but the file you uploaded is identical to the original. Is there a patched version? I owe you bigtime!

 

— Steve

Share this post


Link to post

Now I see that FieldData can be defined for max 256 fields.

    FieldData: array [0..255] of PAnsiChar;

And get rid of setting the length of FieldData for every field.

uDBF.pas

  • Like 1

Share this post


Link to post
1 hour ago, Steve Maughan said:

@Cristian Peța you found it!! When I disable the ASLR in Delphi 11.3 it also runs fine in 64 bit mode. That makes sense.  MANY THANKS!

 

Now the question is, how do I make it work with ASLR enabled.

 

— Steve

 

It will crash if the top thirty-two bits of any pointer handled by the buggy code are not all zeroes. That just happens more often if ASLR is enabled or all the time if ASLR + the high entropy allocator is enabled. 

 

 

  • Like 1

Share this post


Link to post

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

×