Einzelnen Beitrag anzeigen

Rolf Frei

Registriert seit: 19. Jun 2006
629 Beiträge
 
Delphi 11 Alexandria
 
#1

TStringList verhält sich in D11 anders mit enthaltenen #0

  Alt 25. Aug 2022, 01:07
Delphi-Version: 11 Alexandria
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;

Geändert von Rolf Frei (25. Aug 2022 um 01:11 Uhr)
  Mit Zitat antworten Zitat