Hi FPC,

I found that using a TParams.GetByName call using an invalid parameter name 
causes a crash when the TParams is not owned by a TDataset.

I'm not sure whether it is a requirement of TParams usage to have it owned by a 
TDataset object, but otherwise, below is an explanation of what is going wrong.


Now the details about the crash. Start by looking at

dsparams.inc, lin 146 to 151:

 Function TParams.ParamByName(const Value: string): TParam;
 begin
   Result:=FindParam(Value);
   If (Result=Nil) then
     DatabaseErrorFmt(SParameterNotFound,[Value],Dataset);
 end;

If no parameter with name Value is found, it calls DatabaseErrorFmt with its 
formal parameter Component getting the value that Dataset returns. Look at 
TParams.GetDataSet:

dsparams.inc, line 32 to 38:

 Function TParams.GetDataSet: TDataSet;
 begin
   If (FOwner is TDataset) Then
     Result:=TDataset(FOwner)
   else
     Result:=Nil;
 end;

As you can see, Dataset will take value nil if the TParams instance has no 
Owner. Now look at DatabaseErrorFmt:

db.pp, line 1823 to 1827:

 Procedure DatabaseErrorFmt (Const Fmt : String; Args : Array Of const;
                             Comp : TComponent);
 begin
   Raise EDatabaseError.CreateFmt(Format('%s : %s',[Comp.Name,Fmt]),Args);
 end;

No check is done on Assigned(Comp), so the dereferencing Comp.Name will cause 
an Access Violation (instead of a nice 'Parameter blablabla not found' message).


Perhaps we should fix TParams.ParamByName to

 Function TParams.ParamByName(const Value: string): TParam;
 begin
   Result:=FindParam(Value);
   If (Result=Nil) then
     begin
     if DataSet<>nil then
       DatabaseErrorFmt(SParameterNotFound,[Value],DataSet)
     else
       DatabaseErrorFmt(SParameterNotFound,[Value]);
     end;
 end;

or

 Function TParams.ParamByName(const Value: string): TParam;
 var
   TmpDataset:TDataset;
 begin
   Result:=FindParam(Value);
   If (Result=Nil) then
     begin
     TmpDataSet:=DataSet;
     if TmpDataSet<>nil then
       DatabaseErrorFmt(SParameterNotFound,[Value],TmpDataset)
     else
       DatabaseErrorFmt(SParameterNotFound,[Value]);
     end;
 end;


Regards,

Bram Kuijvenhoven
_______________________________________________
fpc-devel maillist  -  [email protected]
http://lists.freepascal.org/mailman/listinfo/fpc-devel

Reply via email to