Einzelnen Beitrag anzeigen

Rolf Frei

Registriert seit: 19. Jun 2006
650 Beiträge
 
Delphi 11 Alexandria
 
#8

AW: Access Violations nach Update auf XE3

  Alt 15. Okt 2012, 15: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 16:19 Uhr)
  Mit Zitat antworten Zitat