Forum > General

Are there some type errors in this StrToBoolEx function in Zeoslib?

(1/1)

vfclists:
Although it is from the Zeoslib issue I think the fault I'm seeing comes from the FreePascal, or it may due to some effects from the defines, string-handling or maybe due to changes in the FPC compile.

On further inspection the call doesn't seem to match the function signatures, so it may be another definition in another file I may have to check.

The full file is at https://github.com/marsupilami79/zeoslib/blob/7.2.14-stable/src/core/ZSysUtils.pas

The actual file


--- Code: Pascal  [+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i < x.length; i++) { x[i].style.maxHeight='none'; x[i].style.height = Math.min(x[i].clientHeight+15,306)+'px'; x[i].style.resize = "vertical";}};} ---function StrToBoolEx(const Str: RawByteString; const CheckInt: Boolean = True): Boolean; overload; {**  Converts a zero terminated raw buffer into boolean value.  @param Str a PAnsiChar value.  @param CheckInt Check for "0" char too?  @param IgnoreTrailingSaces Ignore trailing spaces for fixed char fields f.e.  @return <code>True</code> is Str = 'Y'/'YES'/'T'/'TRUE'/'ON'/<>0}function StrToBoolEx(Str: PAnsiChar; const CheckInt: Boolean = True;  const IgnoreTrailingSaces: Boolean = True): Boolean; overload; {**  Converts a string into boolean value.  @param Str a ZWideString value.  @return <code>True</code> is Str = 'Y'/'YES'/'T'/'TRUE'/'ON'/<>0}function StrToBoolEx(const Str: ZWideString; const CheckInt: Boolean = True): Boolean; overload; {**  Converts a zero terminated UTF16 buffer into boolean value.  @param Str a PWideChar value.  @param CheckInt Check for "0" char too?  @param IgnoreTrailingSaces Ignore trailing spaces for fixed char fields f.e.  @return <code>True</code> is Str = 'Y'/'YES'/'T'/'TRUE'/'ON'/<>0}function StrToBoolEx(Str: PWideChar; const CheckInt: Boolean = True;  const IgnoreTrailingSaces: Boolean = True): Boolean; overload; {**  Converts a boolean into string value.  @param Bool a boolean value.  @return <code>"True"</code> or <code>"False"</code>} 
It is used in the function below, primarily in this section.


The problem line seems to be
--- Code: Pascal  [+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i < x.length; i++) { x[i].style.maxHeight='none'; x[i].style.height = Math.min(x[i].clientHeight+15,306)+'px'; x[i].style.resize = "vertical";}};} ---lValidateUpdateCount := (SQL = '') or StrToBoolEx(SQL); fails to return False when SQL='-1' and I think its definition as string is the cause in the help it is displayed as

Tool tip info during debugging

SQL = ANSISTRING($00007FE14AB85618)^: '-1'
var SQL: string
/home/vfclists/Lazarus/Configs/Lazarus-3.0.0-2023-12-23/onlinepackagemanager/packages/zeosdbo/src/dbc/ZDbcGenericResolver.pas(797,3)
Package
zdbc


The problem section

Line 5 (below, Line 81 in the full function) are where the failure occurs.


--- Code: Pascal  [+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i < x.length; i++) { x[i].style.maxHeight='none'; x[i].style.height = Math.min(x[i].clientHeight+15,306)+'px'; x[i].style.resize = "vertical";}};} ---  // if Property ValidateUpdateCount isn't set : assume it's true  SenderStatement := Sender.GetStatement;  if Assigned(SenderStatement) then begin    SQL := SenderStatement.GetParameters.Values['ValidateUpdateCount'];    lValidateUpdateCount := (SQL = '') or StrToBoolEx(SQL);  end else begin    lValidateUpdateCount := true;  end;   lUpdateCount := Statement.ExecuteUpdatePrepared;  {$IFDEF WITH_VALIDATE_UPDATE_COUNT}  if  (lValidateUpdateCount) and (lUpdateCount <> 1   ) then    raise EZSQLException.Create(Format(SInvalidUpdateCount, [lUpdateCount]));  {$ENDIF} 

On further inspection the call doesn't seem to match the function signatures, so it may be another definition in another file I may have check.

The function that calls StrToBoolEx(param: string)
 

--- Code: Pascal  [+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i < x.length; i++) { x[i].style.maxHeight='none'; x[i].style.height = Math.min(x[i].clientHeight+15,306)+'px'; x[i].style.resize = "vertical";}};} ---{**  Posts updates to database.  @param Sender a cached result set object.  @param UpdateType a type of updates.  @param OldRowAccessor an accessor object to old column values.  @param NewRowAccessor an accessor object to new column values.}procedure TZGenericCachedResolver.PostUpdates(Sender: IZCachedResultSet;  UpdateType: TZRowUpdateType; OldRowAccessor, NewRowAccessor: TZRowAccessor);var  Statement            : IZPreparedStatement;  SQL                  : string;  SQLParams            : TObjectList;  lUpdateCount         : Integer;  lValidateUpdateCount : Boolean;  TempKey              : IZAnyValue;  SenderStatement      : IZStatement;begin  if (UpdateType = utDeleted) and (OldRowAccessor.RowBuffer.UpdateType = utInserted) then    Exit;   case UpdateType of    utInserted:      begin        if InsertStatement = nil then begin          SQL := FormInsertStatement(FInsertParams, NewRowAccessor);          InsertStatement := CreateResolverStatement(SQL);          Statement := InsertStatement;        end;        Statement := InsertStatement;        SQLParams := FInsertParams;      end;    utDeleted:      begin        if not FWhereAll then begin          If DeleteStatement = nil then begin            SQL := FormDeleteStatement(FDeleteParams, OldRowAccessor);            DeleteStatement := CreateResolverStatement(SQL);          end;          Statement := DeleteStatement;          SQLParams := FDeleteParams;        end else begin          FDeleteParams.Clear;  //EH: where columns propably are cached after 1. call          SQL := FormDeleteStatement(FDeleteParams, OldRowAccessor);          if SQL = '' then Exit;          TempKey := TZAnyValue.CreateWithInteger(Hash(SQL));          Statement := FStatements.Get(TempKey) as IZPreparedStatement;          If Statement = nil then begin            Statement := CreateResolverStatement(SQL);            FStatements.Put(TempKey, Statement);          end;          SQLParams := FDeleteParams;        end;      end;    utModified:      begin        FUpdateParams.Clear;  //EH: where columns propably are cached after 1. call        //now what's faster?: caching stmts too by using a hashmap or recreate always        //first of all: we need the new command-stmt        SQL := FormUpdateStatement(FUpdateParams, OldRowAccessor, NewRowAccessor);        If SQL = '' then exit;// no fields have been changed        TempKey := TZAnyValue.CreateWithInteger(Hash(SQL));        UpdateStatement := FStatements.Get(TempKey) as IZPreparedStatement;        If UpdateStatement = nil then begin          UpdateStatement := CreateResolverStatement(SQL);          FStatements.Put(TempKey, UpdateStatement);        end;        Statement := UpdateStatement;        SQLParams := FUpdateParams;      end;    else      Exit;  end;   FillStatement(Statement, SQLParams, OldRowAccessor, NewRowAccessor);   // if Property ValidateUpdateCount isn't set : assume it's true  SenderStatement := Sender.GetStatement;  if Assigned(SenderStatement) then begin    SQL := SenderStatement.GetParameters.Values['ValidateUpdateCount'];    lValidateUpdateCount := (SQL = '') or StrToBoolEx(SQL);  end else begin    lValidateUpdateCount := true;  end;   lUpdateCount := Statement.ExecuteUpdatePrepared;  {$IFDEF WITH_VALIDATE_UPDATE_COUNT}  if  (lValidateUpdateCount) and (lUpdateCount <> 1   ) then    raise EZSQLException.Create(Format(SInvalidUpdateCount, [lUpdateCount]));  {$ENDIF}end;

tetrastes:


--- Quote from: vfclists on October 01, 2024, 05:02:31 pm ---The problem line seems to be
--- Code: Pascal  [+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i < x.length; i++) { x[i].style.maxHeight='none'; x[i].style.height = Math.min(x[i].clientHeight+15,306)+'px'; x[i].style.resize = "vertical";}};} ---lValidateUpdateCount := (SQL = '') or StrToBoolEx(SQL); fails to return False when SQL='-1'

--- End quote ---


Why do you think it must return false?
StrToBoolEx('-1') evaluates to the line 1909 of ZSysUtils.pas:

--- Code: Pascal  [+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i < x.length; i++) { x[i].style.maxHeight='none'; x[i].style.height = Math.min(x[i].clientHeight+15,306)+'px'; x[i].style.resize = "vertical";}};} ---Result := CheckInt and (RawToIntDef(Str, 0) <> 0);CheckInt = true by default (as you don't explicitly set it to false), RawToIntDef('-1', 0) = -1, so Result = true.


Try
--- Code: Pascal  [+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i < x.length; i++) { x[i].style.maxHeight='none'; x[i].style.height = Math.min(x[i].clientHeight+15,306)+'px'; x[i].style.resize = "vertical";}};} ---lValidateUpdateCount := (SQL = '') or StrToBoolEx(SQL, false);

vfclists:

--- Quote from: tetrastes on October 01, 2024, 07:16:19 pm ---

--- Quote from: vfclists on October 01, 2024, 05:02:31 pm ---The problem line seems to be
--- Code: Pascal  [+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i < x.length; i++) { x[i].style.maxHeight='none'; x[i].style.height = Math.min(x[i].clientHeight+15,306)+'px'; x[i].style.resize = "vertical";}};} ---lValidateUpdateCount := (SQL = '') or StrToBoolEx(SQL); fails to return False when SQL='-1'

--- End quote ---


Why do you think it must return false?
StrToBoolEx('-1') evaluates to the line 1909 of ZSysUtils.pas:

--- Code: Pascal  [+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i < x.length; i++) { x[i].style.maxHeight='none'; x[i].style.height = Math.min(x[i].clientHeight+15,306)+'px'; x[i].style.resize = "vertical";}};} ---Result := CheckInt and (RawToIntDef(Str, 0) <> 0);CheckInt = true by default (as you don't explicitly set it to false), RawToIntDef('-1', 0) = -1, so Result = true.


Try
--- Code: Pascal  [+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i < x.length; i++) { x[i].style.maxHeight='none'; x[i].style.height = Math.min(x[i].clientHeight+15,306)+'px'; x[i].style.resize = "vertical";}};} ---lValidateUpdateCount := (SQL = '') or StrToBoolEx(SQL, false);
--- End quote ---

You are right. I was following a forum post on fixing problem and didn't go too deep into checking it. It was all rather ambiguous.

The guidance should have said ValidateUpdateCount should be set to zero 0 or 'False'.

Thaddy:
it is not ambiguous: false (0) is always true.

Navigation

[0] Message Index

Go to full version