View Issue Details

IDProjectCategoryView StatusLast Update
0004606JEDI VCL00 JVCL Componentspublic2011-06-09 22:02
ReportercguserAssigned Tojfudickar 
PrioritynormalSeverityminorReproducibilityalways
Status resolvedResolutionfixed 
Product Version3.33 
Target VersionFixed in Version 
Summary0004606: JvDBSearchEdit user input validation
DescriptionIf JvDBSearchEdit.DataField is connected to TIntegerField, on change it will trigger a "DataSet.Locate(..." passing whatever the user typed in. If the user types any text instead of a valid integer (TIntegerField), locate will give an error.

Code at "fault":

procedure TJvDBCustomSearchEdit.CMChanged(var Msg: TMessage);
...
          if DataSet.Locate(FieldName, Text, FSearchOptions) then


A quick and dirty fix was to encapsulate the call on a try/except block, but it lacks in... elegance, to put it mildly.

procedure TJvDBCustomSearchEdit.CMChanged(var Msg: TMessage);
  ...
        try begin
          if DataSet.Locate(FieldName, Text, FSearchOptions) then
          begin
            LText := Text;
            Text := DataSet.FieldByName(DataField).AsString;
            SelStart := Length(LText);
            SelLength := Length(Text) - SelStart;
          end;
        end; except end;


Would be way better to auto mask the editor on setting DataField, or (if too tricky) at least have the option to set an Edit Mask manually.

I don't think this is strictly a bug in itself, but it would be quite helpful to not have to *manually* fiddle in what the user can type in or not.

To expose the relevance of this a little better, JvDBSearchEdit.DataField may (and does in my situation) point to any TField type (like TFloatField or TDateTimeField and not only TStringField) in a dynamic grid where the search field can be set to whatever field the user choose. As mentioned, DataSet Locate will "crash" with invalid data to find.

It just occurred to me that maybe there is some generic input mask/validator in Jedi that can be plugged into JvDBSearchEdit? Just a thought.

Thank you.

cg
TagsNo tags attached.

Activities

obones

2008-12-22 05:59

administrator   ~0015159

Please provide the zipped sources of an autonomous sample application showing this.

cguser

2008-12-29 08:51

reporter   ~0015189

Sorry for the late reply (still on vacations till next week).

Anyway, I cooked some code to show this (call it from
anywhere like the OnClick of a TButton):


  TClientDataSet *cds = new TClientDataSet(this);

  TField *i = new TIntegerField(cds);
  i->FieldName = "Field1";
  i->DataSet = cds;
  i->FieldKind = fkData;

  cds->CreateDataSet();
  cds->Open();

  for (int j=0;j<10;++j) // Some dummy records...
    cds->AppendRecord(ARRAYOFCONST((j)));

  TDataSource *ds = new TDataSource(this);
  ds->DataSet = cds;

  TJvDBSearchEdit *search = new TJvDBSearchEdit(this);
  search->Parent = this;
  search->DataSource = ds;
  search->DataField = "Field1";

  // Type say "abc"... and it should crash on DataSet.Locate
  // inside of TJvDBCustomSearchEdit.CMChanged message handler


Please advise if the provided sample is insufficient.

As mentioned, I'm not sure if it's a bug by itself, maybe it's more of a shortcoming of the expected functionality. Of course we can't pass a generic string to the Locate function of a DataSet *if* that field happens to be of an integer type.

On normal coding I would force the user to type only integers with a mask on the edit, or, do a StrToIntDef() on the user input before calling Locate.

Now, with TJvDBSearchEdit how can we handle it (generic user input)?

The quick fix that I've used was just to patch the source and wrap the Locate call inside a try/catch block. It works... basically "ignores" invalid inputs from the user. Hardly a proper patch, but surely a pretty easy it is.

obones

2008-12-30 02:39

administrator   ~0015196

No worries for the late reply, but I really want the sources with the associated database, so that I can test in the same conditions as you did.

cguser

2009-01-02 15:53

reporter   ~0015202

Ok, as soon as I'm back in the office (next Wednesday) I shall attach a sample.

Nevertheless, it will be exactly the following steps:
1) Make a new C++ VCL Application
2) put the code that I pasted above on the form constructor
3) ... that's it! there is no third step. Just press F9 and type an "a", it should crash as mentioned.

The code above was tested and it works. There is no need for any other database.
TJvDBSearchEdit is connected into a dataset with a single integer field.

Should I add Project1.cbproj or just Form1.cpp/Form1.dfm/Form1.h?

obones

2009-01-05 00:51

administrator   ~0015208

Add everything, except the compiled files, please.

2009-01-07 03:09

 

Project1.7z (3,554 bytes)

cguser

2009-01-07 03:11

reporter   ~0015215

Project has been attached.

cguser

2011-06-08 18:19

reporter   ~0018701

Every time I download a new version from the svn I need to remember to fix this as above (just encapsulate the Locate call within a try/catch):

procedure TJvDBCustomSearchEdit.CMChanged(var Msg: TMessage);
   ...
         try begin
           if DataSet.Locate(FieldName, Text, FSearchOptions) then
           begin
             LText := Text;
             Text := DataSet.FieldByName(DataField).AsString;
             SelStart := Length(LText);
             SelLength := Length(Text) - SelStart;
           end;
         end; except end;
 
would it be possible to have this commited, as anything fancier would be too much time consuming?

jfudickar

2011-06-09 22:02

developer   ~0018713

I've added a property RaiseLocateException.
Deactivate it and you got your wanted behaviour.

Issue History

Date Modified Username Field Change
2008-11-26 08:13 cguser New Issue
2008-12-22 05:59 obones Note Added: 0015159
2008-12-22 05:59 obones Status new => feedback
2008-12-29 08:51 cguser Note Added: 0015189
2008-12-30 02:39 obones Note Added: 0015196
2009-01-02 15:53 cguser Note Added: 0015202
2009-01-05 00:51 obones Note Added: 0015208
2009-01-07 03:09 cguser File Added: Project1.7z
2009-01-07 03:11 cguser Note Added: 0015215
2009-07-06 14:05 obones Status feedback => acknowledged
2011-06-08 18:19 cguser Note Added: 0018701
2011-06-09 22:02 jfudickar Note Added: 0018713
2011-06-09 22:02 jfudickar Status acknowledged => resolved
2011-06-09 22:02 jfudickar Resolution open => fixed
2011-06-09 22:02 jfudickar Assigned To => jfudickar