View Issue Details

IDProjectCategoryView StatusLast Update
0006063JEDI Code LibraryJclSimpleXmlpublic2013-06-16 23:03
ReporterwestphalAssigned Tojfudickar 
PrioritynormalSeveritymajorReproducibilityalways
Status feedbackResolutionopen 
Product VersionVersion 2.5 (Subversion repository/Daily zips) 
Target VersionFixed in Version 
Summary0006063: TJclSimpleXML insert item lead to a raise error
Descriptionif a node is inserted in another items list than it's own parent list, the item is freed.

Additional Informationprocedure TForm3.Button4Click(Sender: TObject);
var
  xml : TJclSimpleXML;
  pa,i1,i2,Node : TJclSimpleXMLElem;
begin
  xml := TJclSimpleXML.Create;
  try
    pa := xml.Root;
    pa.Name := 'conf';

    i1 := pa.Items.Add('item1');
      node := i1.Items.Add('sub1');
    i2 := pa.Items.Add('item2');
      // next line free node because it's owned by another Items list
      i2.Items.Insert(node,0);
      i2.Items.Delete(0); // <--- raise

  finally
    xml.Free;
  end;
end;
TagsNo tags attached.
Fixed in GIT commit
Fixed in SVN revision
IDE versionAll

Activities

westphal

2013-01-15 15:16

reporter   ~0020344

Last edited: 2013-01-16 16:23

proposed correction:


function TJclSimpleItemHashedList.Extract(Item: TJclSimpleItem): TJclSimpleItem;
begin
  Result := TJclSimpleItem(inherited Extract(Item));
  InvalidateHash;
end;


procedure TJclSimpleXMLElems.InsertChild(const Value: TJclSimpleXMLElem; Index: Integer);
var
  NamedIndex: Integer;
begin
  CreateElems;

  // If there already is a container, notify it to remove the element
  if Assigned(Value.Parent) then begin
    if (value.parent<>FParent) then begin
      if FNamedElems <> nil then begin
        NamedIndex := FNamedElems.IndexOfName(Value.Name);
        if NamedIndex >= 0 then
           TJclSimpleXMLNamedElems(FNamedElems.SimpleItems[NamedIndex]).FItems.Remove(Value);
      end;
      Value.FParent.items.FElems.Extract(Value); //EW here is the real difference
      Value.FParent := nil;
      Value.FSimpleXML := nil;
    end else begin
      Value.Parent.Items.Notify(Value, opRemove);
    end;
  end;

  FElems.Insert(Index, Value);

  if FNamedElems <> nil then
  begin
    NamedIndex := FNamedElems.IndexOfName(Value.Name);
    if NamedIndex >= 0 then
      TJclSimpleXMLNamedElems(FNamedElems.SimpleItems[NamedIndex]).FItems.Add(Value);
  end;

  Notify(Value, opInsert);
end;

westphal

2013-01-16 18:41

reporter   ~0020402

Index: JclSimpleXml.pas
===================================================================
--- JclSimpleXml.pas (revision 3891)
+++ JclSimpleXml.pas (working copy)
@@ -94,6 +94,7 @@
     constructor Create(ACaseSensitive: Boolean);
     destructor Destroy; override;
     function Add(Item: TJclSimpleItem): Integer;
+ function Extract(Item: TJclSimpleItem): TJclSimpleItem;
     procedure Clear; override;
     function IndexOfSimpleItem(Item: TJclSimpleItem): Integer;
     function IndexOfName(const Name: string): Integer;
@@ -1047,6 +1048,13 @@
   end;
 end;
 
+function TJclSimpleItemHashedList.Extract(Item: TJclSimpleItem): TJclSimpleItem;
+begin
+ Result := TJclSimpleItem(inherited Extract(Item));
+ InvalidateHash;
+end;
+
 function TJclSimpleItemHashedList.GetSimpleItem(Index: Integer): TJclSimpleItem;
 begin
   Result := TJclSimpleItem(GetItem(Index));
@@ -1115,10 +1123,8 @@
 begin
   if (Action = lnDeleted) and (FNameHash <> nil) then
   begin
- if FCaseSensitive then
- FNameHash.Remove(TJclSimpleItem(Ptr).Name)
- else
- FNameHash.Remove(UpperCase(TJclSimpleItem(Ptr).Name));
+ InvalidateHash;
   end;
   inherited Notify(Ptr, Action);
 end;
@@ -2571,8 +2577,20 @@
   CreateElems;
 
   // If there already is a container, notify it to remove the element
- if Assigned(Value.Parent) then
- Value.Parent.Items.Notify(Value, opRemove);
+ if Assigned(Value.Parent) then begin
+ if (value.parent<>FParent) then begin
+ if FNamedElems <> nil then begin
+ NamedIndex := FNamedElems.IndexOfName(Value.Name);
+ if NamedIndex >= 0 then
+ TJclSimpleXMLNamedElems(FNamedElems.SimpleItems[NamedIndex]).FItems.Remove(Value);
+ end;
+ Value.FParent.items.FElems.Extract(Value);
+ Value.FParent := nil;
+ Value.FSimpleXML := nil;
+ end else begin
+ Value.Parent.Items.Notify(Value, opRemove);
+ end;
+ end;
 
   FElems.Insert(Index, Value);

jfudickar

2013-06-16 23:03

developer   ~0020531

Commited to github

Issue History

Date Modified Username Field Change
2013-01-15 14:45 westphal New Issue
2013-01-15 14:45 westphal IDE version => All
2013-01-15 15:16 westphal Note Added: 0020344
2013-01-16 16:23 westphal Note Edited: 0020344
2013-01-16 18:41 westphal Note Added: 0020402
2013-06-16 23:03 jfudickar Note Added: 0020531
2013-06-16 23:03 jfudickar Assigned To => jfudickar
2013-06-16 23:03 jfudickar Status new => feedback