Habe eben einen unschönen Bug (oder Absicht?) in der TSrtingList, genauer in TString.SetTextStr, gefunden, den es in 10.3 noch nicht gab. Im konkreten Fall lade ich ein
HTML-Template in eine TStringList (TPageProducer.HTMLDoc.LoadFormFile(..)). Nun hat sich hier ein Template eingeschlichen das anscheinend seit Jaharen ein #0 Char ehthalten hat. Diese war bisher keien Problem, da die StringList solche #0 (und #13#10) bisher überlesen hat.
Das Problem ist nun, dass enthaltene #0 Character in D11 nicht mehr herausgefiltert werden, sondern im SL.Text enthalten bleiben. Das hat nun den Nebeneffekt das der TPageProducer.Content nicht mehr das ganze Template verabeitet und alles nach dem #0 fehlt. Das #0 ist für den Parser im TPageProducer eine Fileende.
Mich würde nun interessieren, wieso TString.SetTextStr komplett umgeschrieben wurde und die #0 Zeichen nicht mehr behandelt. Ist das Absicht oder eine Bug?
Code aus D10.3:
Delphi-Quellcode:
procedure TStrings.SetTextStr(const Value: string);
var
P, Start, LB: PChar;
S: string;
LineBreakLen: Integer;
begin
BeginUpdate;
try
Clear;
P := Pointer(Value);
if P <> nil then
if CompareStr(LineBreak, sLineBreak) = 0 then
begin
// This is a lot faster than using StrPos/AnsiStrPos when
// LineBreak is the default (#13#10)
while P^ <> #0 do
begin
Start := P;
while not (P^ in [#0, #10, #13]) do Inc(P);
SetString(S, Start, P - Start);
Add(S);
if P^ = #13 then Inc(P);
if P^ = #10 then Inc(P);
end;
end
else
begin
LineBreakLen := Length(LineBreak);
while P^ <> #0 do
begin
Start := P;
LB := AnsiStrPos(P, PChar(LineBreak));
while (P^ <> #0) and (P <> LB) do Inc(P);
SetString(S, Start, P - Start);
Add(S);
if P = LB then
Inc(P, LineBreakLen);
end;
end;
finally
EndUpdate;
end;
end;
Code aus D11.1:
Delphi-Quellcode:
procedure TStrings.SetTextStr(
const Value:
string);
var
P, PCurVal, PCurLB, PStartVal, PEndVal, PStartLB, PEndLB: PChar;
S:
string;
LineBreakLen: Integer;
begin
BeginUpdate;
try
Clear;
P := Pointer(Value);
if P =
nil then
Exit;
LineBreakLen := Length(LineBreak);
if LineBreakLen = 0
then
begin
Add(Value);
Exit;
end;
PEndVal := P + Length(Value);
// When LineBreak is:
// * sLineBreak - for compatibility with Windows, Posix and old macOS platforms,
// we handle #13#10, #10 and #13 as it would be #13#10.
// * NOT sLineBreak - we use strict checking for LineBreak.
if CompareStr(LineBreak, sLineBreak) = 0
then
begin
while P < PEndVal
do
begin
PStartVal := P;
while (P < PEndVal)
and not (P^
in [#10, #13])
do Inc(P);
SetString(S, PStartVal, P - PStartVal);
Add(S);
if P^ = #13
then Inc(P);
if P^ = #10
then Inc(P);
end;
Exit;
end;
PStartLB := Pointer(LineBreak);
PEndLB := PStartLB + LineBreakLen;
PCurLB := PStartLB;
PStartVal := P;
while P < PEndVal
do
begin
while (P < PEndVal)
and (P^ <> PStartLB^)
do
Inc(P);
if P < PEndVal
then
begin
PCurVal := P + 1;
Inc(PCurLB);
while (PCurLB < PEndLB)
and (PCurVal < PEndVal)
and (PCurVal^ = PCurLB^)
do
begin
Inc(PCurVal);
Inc(PCurLB)
end;
if PCurLB = PEndLB
then
begin
SetString(S, PStartVal, P - PStartVal);
Add(S);
P := PCurVal;
PStartVal := P;
end
else
Inc(P);
PCurLB := PStartLB;
end;
end;
if P > PStartVal
then
begin
SetString(S, PStartVal, P - PStartVal);
Add(S);
end;
finally
EndUpdate;
end;
end;