MSSQL + Problem with StringReplace function for #0
Posted: 15.11.2014, 13:45
In unit ZDbcDbLibUtils.pas is used to replace #0 in string format for
"stAsciiStream, stUnicodeStream, stBinaryStream:" with ''.
The Delphi StringReplace function (at least Delphi 7 or Delphi XE2 one) uses AnsiPos and later StrPosLen witch ignores the #0 character so the replacement does not work resulting in unterminated string.
The isue was also presented in http://zeosbugs.firmos.at/view.php?id=267..
For solving this issue we have to replace then AnsiPos with PosEx function.
So I included in ZSysUtils a copy of StringReplace function for both AnsiString and String and replace the AnsiPos with PosEx.
Then I replaced all the implication of StringReplace focusing on ZDbcDbLibUtils.pas and ZDbcPostgreSqlUtils.pas where was replacement of #0.
Then all the references of StringReplace in all ZeosDBO sources.
"stAsciiStream, stUnicodeStream, stBinaryStream:" with ''.
The Delphi StringReplace function (at least Delphi 7 or Delphi XE2 one) uses AnsiPos and later StrPosLen witch ignores the #0 character so the replacement does not work resulting in unterminated string.
The isue was also presented in http://zeosbugs.firmos.at/view.php?id=267.
Code: Select all
StringReplace(GetValidatedAnsiStringFromBuffer(TempBlob.GetBuffer, TempBlob.Length, ConSettings, zCP_UTF8), #0, '', [rfReplaceAll]), '''')
For solving this issue we have to replace then AnsiPos with PosEx function.
So I included in ZSysUtils a copy of StringReplace function for both AnsiString and String and replace the AnsiPos with PosEx.
Code: Select all
function StringReplace(const S, OldPattern, NewPattern: AnsiString;
Flags: TReplaceFlags): AnsiString;
var
SearchStr, Patt, NewStr: AnsiString;
Offset: Integer;
begin
if rfIgnoreCase in Flags then
begin
SearchStr := AnsiUpperCase(S);
Patt := AnsiUpperCase(OldPattern);
end else
begin
SearchStr := S;
Patt := OldPattern;
end;
NewStr := S;
Result := '';
while SearchStr <> '' do
begin
Offset := [b]AnsiStrings.PosEx(Patt, SearchStr);[/b]
if Offset = 0 then
begin
Result := Result + NewStr;
Break;
end;
Result := Result + Copy(NewStr, 1, Offset - 1) + NewPattern;
NewStr := Copy(NewStr, Offset + Length(OldPattern), MaxInt);
if not (rfReplaceAll in Flags) then
begin
Result := Result + NewStr;
Break;
end;
SearchStr := Copy(SearchStr, Offset + Length(Patt), MaxInt);
end;
end;
Then all the references of StringReplace in all ZeosDBO sources.