Einzelnen Beitrag anzeigen

cltom

Registriert seit: 22. Sep 2005
221 Beiträge
 
Delphi 12 Athens
 
#1

Integerüberlauf bei Hash-Funktion

  Alt 10. Apr 2024, 16:28
Delphi-Version: 12 Athens
Hallo,

folgende Funktion wird seit 15+ Jahren in einem Projekt verwendet, ohne dass da je ein Problem aufgetaucht wäre. Es stammt aus der Hash-Library von Ciaran McCreesh. Man kann sicher darüber nachdenken, ob man die heute noch braucht, sie zu ersetzen würde allerdings einige bedeutende Änderungen mitbringen, die ich nicht (auf die Schnelle) lostreten wollte.

Nun wirft die Funktion aber einen Integer-Überlauf mit einem Argument, das seit ebenso 15 Jahren auf diese Funktion trifft.

Delphi-Quellcode:
  function HashThis(const s: string): cardinal;
  var
    h, g, i: cardinal;
  begin
    if (s = '') then
      raise EHashInvalidKeyError.Create('Key cannot be an empty string');
    h := $12345670;
    for i := 1 to Length(s) do begin
      h := (h shl 4) + ord(s[i]);
      g := h and $f0000000;
      if (g > 0) then
        h := h or (g shr 24) or g;
    end;
    result := h;
  end;

Augenscheinlich ist der Schritt

h := (h shl 4) + ord(s[i]); der Auslöser.

Was die Suche ergeben hat ist, dass in einem alten Backup des Projekts der Fehler nicht auftritt. Da waren Überlaufswarnungen deaktiviert, auch wenn ich dort aber die Überlaufswarnungen aktiviere, tritt kein Fehler auf!? Da kann ich die Funktion mit einem Problemstring schrittweise durchgehen, und es kommt kein Fehler.
Wenn man ein neues Projekt startet und einen Problemstring übergibt, tritt der Fehler ebenfalls auf.
Umgekehrt, wenn ich in der neuen Fassung des Projekts (mit neuer Projektdatei) die Überlaufswarnungen deaktiviere, kommt der Fehler dennoch (alles unter 32 bit debug, wo ich mal auch kompiliere).

Es liegt also am String und Projekteinstellungen, die sich mir noch nicht erschlossen haben.

Die eigentliche Frage: warum ergibt diese Funktion bei gewissen Strings einen Überlauf? Längere Strings sind anfälliger, aber ein einziger Buchstabe verschoben von einem "Problemstring" ergibt schon keinen Fehler mehr. Die Strings ändern ist keine echte Option (auch wenn es leicht wäre), da die Strings im Dateiformat zum speichern/öffnen verwendet werden - wieder größerer Umbau. Warum aber hängt das von irgendwelchen Projekteinstellungen ab?

hat jemand einen Blick, wie man an das reparieren könnte?

Danke!
  Mit Zitat antworten Zitat