View Issue Details

IDProjectCategoryView StatusLast Update
0037560FPCFCLpublic2020-08-13 10:18
ReporterBBaz Assigned ToMichael Van Canneyt  
PrioritynormalSeverityminorReproducibilityalways
Status resolvedResolutionno change required 
Product Version3.2.0 
Summary0037560: regression, deserializing empty TCollection dont clear the current content anymore
Descriptionwhen you deserialize and empty TCollection from a textual stream ( possibly also binary stream),
the current content is not cleared, while it was in previous FCL versions (up to, included, 3.0.2).
Steps To Reproducerun this program, the second assertionb should pass but fails:

---
{$Mode objfpc}{$H+}{$Assertions on}
program Project1;

uses Classes;

type
  TItem = class(TCollectionItem)
  public
    fmember: integer;
  published
    property member: integer read fmember write fmember;
  end;

  TCol = class(TComponent)
  strict private
    fitems: TCollection;
    procedure setItems(i: TCollection);
  public
    procedure loadFromString(const s: string);
    constructor create(aOwner: TComponent); override;
    destructor destroy; override;
  published
    property items: TCollection read fitems write setItems;
  end;

procedure TCol.setItems(i: TCollection);
begin
  fitems.Assign(i);
end;

procedure TCol.loadFromString(const s: string);
var
  txt: TmemoryStream;
  bin: TMemoryStream;
begin
  txt := TMemoryStream.Create;
  bin := TMemoryStream.Create;
  try
    txt.Write(s[1], length(s));
    txt.Position:=0;
    try
      ObjectTextToBinary(txt, bin);
    except
      exit;
    end;
    bin.Position:=0;
    bin.ReadComponent(self);
  finally
    bin.Free;
    txt.Free;
  end;
end;

constructor TCol.create(aOwner: TComponent);
begin
  inherited create(aOwner);
  fitems := TCollection.Create(TItem);
end;

destructor TCol.destroy;
begin
  fItems.free;
  inherited;
end;

var
  c: TCol;
  s: string;

begin
  c := TCol.create(nil);
  try
    c.items.Add();
    assert(c.items.count = 1); // OK
    s := 'object TCol'0000013'items=<>'0000013'end';
    c.loadFromString(s);
    assert(c.items.count = 0); // NG
  finally
    c.free;
  end;
end.
---
TagsNo tags attached.
Fixed in Revision
FPCOldBugId
FPCTarget-
Attached Files

Activities

BBaz

2020-08-13 00:05

reporter   ~0124814

ah common this again...

In the test case 0000013 is for <hastag>13 i.e CR.

Michael Van Canneyt

2020-08-13 01:32

administrator   ~0124815

The program behaves the same since version 3.0.0

home:~> ppcx64-3.0.0 tser.pp -S2h
/usr/bin/ld: warning: link.res contains output sections; did you forget -T?
home:~> ./tser
An unhandled exception occurred at $000000000040018C:
EAssertionFailed: Assertion failed (tser.pp, line 77)
  $000000000040018C

home:~> ppcx64-3.0.2 tser.pp -S2h
/usr/bin/ld: warning: link.res contains output sections; did you forget -T?
home:~> ./tser
An unhandled exception occurred at $000000000040018C:
EAssertionFailed: Assertion failed (tser.pp, line 77)
  $000000000040018C

home:~> ppcx64-3.0.4 tser.pp -S2h
/usr/bin/ld: warning: link.res contains output sections; did you forget -T?
home:~> ./tser
An unhandled exception occurred at $000000000040018C:
EAssertionFailed: Assertion failed (tser.pp, line 77)
  $000000000040018C

home:~> ppcx64-3.2.0 tser.pp -S2h
^[[Ahomeppcx64-3.2.0 tser.pp -S2h
home:~> ./tser
An unhandled exception occurred at $000000000042C590:
EAssertionFailed: Assertion failed (tser.pp, line 77)
  $000000000042C590


home:~> ppcx64 tser.pp -S2h
home:~> ./tser
An unhandled exception occurred at $000000000042F825:
EAssertionFailed: Assertion failed (tser.pp, line 77)
  $000000000042F825

The patch that changed the behaviour for empty collections is 12 years old.

------------------------------------------------------------------------
r11348 | Almindor | 2008-07-07 23:21:44 +0200 (Mon, 07 Jul 2008) | 2 lines

* patch from Vincent to fix TReader.ReadCollection calling clear() logic

------------------------------------------------------------------------

So I don't think this is a regression.

BBaz

2020-08-13 08:57

reporter   ~0124818

I've tracked how the regression manifests in my software and it is possible that I didn't see the problem until recently because until a certain change, I cleared the representation of the collection before deserializing.

That being said I'm curious about the rationale of not clearing a collection, like in my test case.

Michael Van Canneyt

2020-08-13 10:18

administrator   ~0124824

The current code is for Delphi compatibility, as far as I know.

Issue History

Date Modified Username Field Change
2020-08-13 00:04 BBaz New Issue
2020-08-13 00:05 BBaz Note Added: 0124814
2020-08-13 01:32 Michael Van Canneyt Assigned To => Michael Van Canneyt
2020-08-13 01:32 Michael Van Canneyt Status new => resolved
2020-08-13 01:32 Michael Van Canneyt Resolution open => no change required
2020-08-13 01:32 Michael Van Canneyt FPCTarget => -
2020-08-13 01:32 Michael Van Canneyt Note Added: 0124815
2020-08-13 08:57 BBaz Note Added: 0124818
2020-08-13 10:18 Michael Van Canneyt Note Added: 0124824