Menu

#85 Error writing big numbers - wrong datatype in

Win32/Linux
open
nobody
None
1
2017-06-07
2016-02-19
Karel Rys
No

Error in:
function IntToStrWidth(Val: {$ifdef SUPPORT_INT64}Int64{$else}Integer{$endif}; const FieldSize: Integer; const Dest: PAnsiChar; Pad: Boolean; PadChar: AnsiChar): Integer;
var
FloatResult: TFloatResult;
Negative: Boolean;
IntValue: Integer;
Buffer: array[0..{$ifdef SUPPORT_INT64}18{$else}9{$endif}] of AnsiChar;
P: PAnsiChar;

IntValue must be declared as Int64, or probably as
var IntValue: {$ifdef SUPPORT_INT64} Int64 {$else} Integer {$endif};

When using Integer and saving a number 3000000000, you get just garbage written into data field.

Discussion

  • Paul Baker

    Paul Baker - 2016-02-29

    What is the type, size and precision of the field? There seems little doubt there is a problem here, but I am having difficulty knowing how to reproduce it.

     

    Last edit: Paul Baker 2016-02-29
  • Karel Rys

    Karel Rys - 2016-02-29

    Is is numeric(12,0). I am attaching an example (field POSLFP).

     
  • Paul Baker

    Paul Baker - 2016-03-04

    Here is complete sample code to reproduce the problem.

    program Test;
    
    uses
      db,
      dbf;
    
    var
      ADbf: TDbf;
      FieldDef: TFieldDef;
    begin
      ADbf := TDbf.Create(nil);
      try
        ADbf.TableName := 'test.dbf';
        FieldDef := ADbf.FieldDefs.Add as TFieldDef;
        FieldDef.Name := 'TEST';
        FieldDef.DataType := ftFloat;
        FieldDef.Size := 12;
        FieldDef.Precision := 0;
        ADbf.CreateTable;
        ADbf.Open;
        ADbf.Insert;
        try
          ADbf['TEST'] := 3000000000;
          ADbf.Post;
        except
          ADbf.Cancel;
          raise;
        end;
      finally
        ADbf.Free;
      end;
    end.
    

    If range checking is on, there is a Range Check Error.

    If range checking is off, it writes an invalid value to the field, "/.',').'", that cannot be read back. This is because the Val parameter is positive whereas the IntValue parameter, which is always supposed to be positive, is negative.

     

    Last edit: Paul Baker 2016-03-04
  • Paul Baker

    Paul Baker - 2016-03-04

    Fixed in v7.0.2 exactly as Karel proposed.

    I don't think I have access to close the ticket.

     
  • Stephane Senecal

    Is this correction is supposed to be in SVN? Beacause it is not.

     
  • Paul Baker

    Paul Baker - 2017-06-07

    I see that for the ftLargeInt field type, TDbfFile.SetFieldData() calls IntToStrWidth(), which is declared exactly as above.

    This change was first made in the paulenandrew branch with a commit that adds more robust Numeric (N) and Float (F) field value translation. This should also fix bug 85, but did not specifically reference it at the time.
    https://sourceforge.net/p/tdbf/code/433

    This change was merged into trunk with this commit.
    https://sourceforge.net/p/tdbf/code/641

    This change was documented as fixing bug 85 in this commit.
    https://sourceforge.net/p/tdbf/code/515

    Can you reproduce this or a related bug? If so, please provide SVN revision number or release version, steps to reproduce, expected behaviour and actual behaviour.

     
    • Stephane Senecal

      I'm using the released version 7.0.1. You said that it was fixed in 7.0.2, but it is nowhere to be seen.
      If you check the latest version of the file dbf_prssupp.pas (https://sourceforge.net/p/tdbf/code/HEAD/tree/trunk/src/dbf_prssupp.pas) at line 356, the variable IntValue is still of type Integer instead of Int64. This cause a range check error at line 367 ou 369 (IntValue := Val) for very large values of Val.

      I hope it's just a commit problem. If not, I'll try to make a sample.

       
      • Paul Baker

        Paul Baker - 2017-06-08

        You are correct! As you see from the history I mentioned, fixing bug 85 was not the original purpose for my change. I later thought it fixed bug 85 and documented that, but I was wrong. It only changes it to a different problem, a Range Check Error.

        I believe I have fixed it in revision 663. Can you verify that, please?
        https://sourceforge.net/p/tdbf/code/663

        I did not change history.txt, because the existing entry covers it and it was never released like it was.

        I remember now that 7.0.2 is not released. There are very few (I think two) people that have rights to this project that are needed to publish a release.

         
        • Stephane Senecal

          It works, thank you.

           

Log in to post a comment.