Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Algorithmen, Datenstrukturen und Klassendesign (https://www.delphipraxis.net/78-algorithmen-datenstrukturen-und-klassendesign/)
-   -   Delphi Crash bei TBytes Typecast (https://www.delphipraxis.net/217075-crash-bei-tbytes-typecast.html)

TurboMagic 21. Apr 2025 18:41

Crash bei TBytes Typecast
 
Hallo,

ein Nutzer der DEC hat einen Crash gemeldet. Ich kann den mit dessen
Beispielprogramm nachstellen, ich verstehe aber noch nicht warum das passiert.

Es gibt diese Typdeklarationen:
Delphi-Quellcode:
  /// <summary>
  ///   Replacement for PByteArray
  /// </summary>
  PUInt8Array = ^TInt8Array;
  TInt8Array = array[0..MaxInt-1] of Byte;
Der Crash passiert hier drin:

Delphi-Quellcode:
procedure TDECCipherModes.EncodeGCM(Source, Dest: PUInt8Array; Size: Integer);
var
  PlainText,
  CipherText : TBytes;
begin
  if (Size > 0) then
  begin
    PlainText := TBytes(@Source^);
    SetLength(PlainText, Size);
Crash>   CipherText := TBytes(@Dest^);
    SetLength(CipherText, Size);
  end
  else
  begin
    SetLength(PlainText, 0);
    SetLength(CipherText, 0);
  end;

  FGCM.EncodeGCM(PlainText, CipherText, Size);
end;
Es gibt da eine Zugriffsverletzung.
Das SetLength(PlainText, Size) und SetLength(CipherText, Size) habe ich schon ergänzt.

EncodeGCM wird von dieser Methode aus aufgerufen:
Delphi-Quellcode:
procedure TDECCipherModes.Encode(const Source; var Dest; DataSize: Integer);
begin
  EncodeGCM(@Source, @Dest, DataSize);
end;
Debugge ich doert hin liefert Assigned(@Dest) unter Watches true

Das Testprogramm übergibt diese Variablen an Encode:

ciphText, refCipherText : Array[0..3] of LongWord;

1. Warum crasht der Typecast CipherText := TBytes(@Dest^);

2. Kann man das EncodeGCM evtl. irgendwie besser schreiben?

himitsu 21. Apr 2025 19:51

AW: Crash bei TBytes Typecast
 
Natürlich muß das knallen :!:

Lösung: SetLength und danach Delphi-Referenz durchsuchenMove vom Parameter in diese Variable.


TBytes ist ein dynamisches Array, welches wie String/AnsiString
eine Kontrollstreuktur mit Referenzzählung und Längenangabe enthält,
was bei einem statischen Array fehlt.

Andersrum geht es aber, also TByte in einen Pointer auf ein statisches Array zu casten,
genauso wie String zu PChar.


Ja, PChar zu String "geht", aber das ist kein Cast, sondern CompilerMagic,
da hierfür in eine entsprechende Funktion der System.pas umgeleitet wird.

TurboMagic 21. Apr 2025 20:18

AW: Crash bei TBytes Typecast
 
Hallo,

danke für die Infos!
Damit kann ich es sicher vorübergehend fixen.
Eigentlich will man aber vermutlich das Umkopieren der Daten vermeiden,
damit wäre es wohl stärker umzubauen, was vorher analysiert werden muss.
Aber natürlich ist es wichtig den Crash schnellstmöglich zu beseitigen,
selbst wenn das die Performance vorübergehend verschlechtert.

jaenicke 21. Apr 2025 21:12

AW: Crash bei TBytes Typecast
 
Ich kenne den restlichen Quelltext nicht, aber für mein Empfinden wäre es, wenn die Zielgröße feststeht (wie hier), die sauberste Variante, wenn der Aufrufer nur korrekt dimensionierte Arrays übergeben darf.

Dann werden dahinter nur Pointer übergeben, was auch performancemäßig sauber ist. Wenn dann noch FGCM.EncodeGCM einfach PUInt8Array bekäme...


Alle Zeitangaben in WEZ +1. Es ist jetzt 00:04 Uhr.

Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz