AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Thema durchsuchen
Ansicht
Themen-Optionen

Access Violations nach Update auf XE3

Ein Thema von Nersgatt · begonnen am 8. Okt 2012 · letzter Beitrag vom 15. Okt 2012
Antwort Antwort
Benutzerbild von Nersgatt
Nersgatt

Registriert seit: 12. Sep 2008
Ort: Emlichheim
693 Beiträge
 
Delphi 10.1 Berlin Professional
 
#1

AW: Access Violations nach Update auf XE3

  Alt 10. Okt 2012, 12:41
So, das Problem ist umzingelt.
Das Problem tritt beim TStringField innerhalb des TClientDataSet auf. Aber nur in dem Fall, wenn TStringField.Size kleiner ist, als das Feld in der Datenbank.
Beispiel: ich habe in der Datenbank ein Feld VarChar(30) und das TStringField, worein die Daten solle hat nur die Size von 20. Dann kracht es.

Nun ist die Frage: ist das ein Fehler in der DB.Data.pas, oder sind wir selbst schuld? Delphi 2010 hatte das noch problemlos geschluckt, wenn das Feld zu klein ist.
Jens
  Mit Zitat antworten Zitat
Rolf Frei

Registriert seit: 19. Jun 2006
656 Beiträge
 
Delphi 11 Alexandria
 
#2

AW: Access Violations nach Update auf XE3

  Alt 10. Okt 2012, 18:19
Ich kann das selber auch reproduzieren. Das ist zu 100% nicht dein Fehler. Ist leider ein weiterer sehr übler Bug und betrifft nicht das TClientDataset, sondern jedes von TDataset abgeleitete Objekt. Mein Test benutzt eine 3rd Party Komponente und auch damit kann ich es reproduzieren.

Bitte melde das mit einem Beispiel in QC.

[EDIT]
Bin nicht sicher ob das überhaupt was mit dem TDataset zu tun hat oder ob es am TDBGrid liegt. Der AV tritt in TDBGridInplaceEdit.UpdateContents bei der Zeile:
Font.Assign(Column.Font);

Wenn ich da aber schrittweise debugge, kann ich nicht sehen was da falsch sein soll. Bin daher überhaupt nicht sicher was zu diesem Fehler führt.

[EDIT2]
Habe nun mal das DB Grid entfernt und ein normales TDBEdit angehängt. Auch damit knallt es. Manchmal erst beim Beenden der Applikation. Wird also doch irgendwie mit TField.Size zusammen hängen.

Geändert von Rolf Frei (10. Okt 2012 um 18:36 Uhr)
  Mit Zitat antworten Zitat
Rolf Frei

Registriert seit: 19. Jun 2006
656 Beiträge
 
Delphi 11 Alexandria
 
#3

AW: Access Violations nach Update auf XE3

  Alt 15. Okt 2012, 14:41
Habe mir das nun mal genauer angeschaut und habe das Problem gefunden. Da wird in TStringField.GetValue zu wenig Buffer alloziert, wenn Size kleiner ist als das effektive DB Feld. Habe folgenden Fix gemacht und nun scheint alles bestens zu laufen. Damit sollten deine AV's Geschichte sein. Habe übrigens einen QC-Eintrag mit meinem FIX erstellt.

Einen gleichartigen Fix sollte man auch noch bei TWideStringField.GetValue machen.)

FIX für TStringField.GetValue:
Delphi-Quellcode:
function TStringField.GetValue(var Value: AnsiString): Boolean;
var
  Buffer: TValueBuffer;
  NullIndex: Integer;
  Str: string;
begin
  // orig. XE3
  // SetLength(Buffer, DataSize);

  // === Fix as in older Delphi Versions ===
  if DataSize > dsMaxStringSize + 1 then
    SetLength(Buffer, DataSize)
  else
    SetLength(Buffer, dsMaxStringSize + 1);
  // === End of Fix ===

  Result := GetData(Buffer);
  if Result then
  begin
    if Transliterate and (Buffer <> nil) and (Buffer[0] <> 0) then
      DataSet.Translate(PAnsiChar(@Buffer[0]), PAnsiChar(@Buffer[0]), False);
    Str := TEncoding.ANSI.GetString(Buffer);
    NullIndex := Str.IndexOf(#0);
    if NullIndex >= 0 then
      Value := AnsiString(Str.Remove(NullIndex))
    else
      Value := AnsiString(Str);
  end;
end;
Und hier für TWideStringField:
Delphi-Quellcode:
function TWideStringField.GetValue(var Value: string): Boolean;
var
  Buffer: TValueBuffer;
  NullIndex: Integer;
  Str: string;
begin
  // orig. XE3
  // SetLength(Buffer, ((DataSize div 2) + 1) * SizeOf(Char));

  // rf
  // === Fix as in older Delphi Versions ===
  if DataSize > ((dsMaxStringSize div 2) + 1) * SizeOf(Char) then
    SetLength(Buffer, ((DataSize div 2) + 1) * SizeOf(Char))
  else
    SetLength(Buffer, ((dsMaxStringSize div 2) + 1) * SizeOf(Char));
  // === End of Fix ===

  Result := GetData(Buffer, False);
  if Result then
  begin
    Str := TEncoding.Unicode.GetString(Buffer);
    NullIndex := Str.IndexOf(#0);
    if NullIndex >= 0 then
      Value := Str.Remove(NullIndex)
    else
      Value := Str;
  end;
end;

Geändert von Rolf Frei (15. Okt 2012 um 15:19 Uhr)
  Mit Zitat antworten Zitat
Antwort Antwort


Forumregeln

Es ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are aus

Gehe zu:

Impressum · AGB · Datenschutz · Nach oben
Alle Zeitangaben in WEZ +1. Es ist jetzt 19:09 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