Skip to content

Commit

Permalink
CycloneDX#348 implement deep copy rather than serialization
Browse files Browse the repository at this point in the history
  • Loading branch information
thompson-tomo committed Sep 5, 2024
1 parent a42f0bf commit c93e130
Show file tree
Hide file tree
Showing 74 changed files with 1,348 additions and 210 deletions.
4 changes: 1 addition & 3 deletions src/CycloneDX.Core/BomUtils.cs
Original file line number Diff line number Diff line change
Expand Up @@ -254,9 +254,7 @@ internal static Bom CopyBomAndDowngrade(Bom bom)

public static Bom Copy(this Bom bom)
{
var protoBom = Protobuf.Serializer.SerializeForDeepCopy(bom);
var bomCopy = Protobuf.Serializer.Deserialize(protoBom);
return bomCopy;
return (Bom)bom.Clone();
}

public static void EnqueueMany<T>(this Queue<T> queue, IEnumerable<T> items)
Expand Down
31 changes: 27 additions & 4 deletions src/CycloneDX.Core/Models/Annotation.cs
Original file line number Diff line number Diff line change
Expand Up @@ -20,17 +20,26 @@
using System.Xml.Serialization;
using System.Text.Json.Serialization;
using ProtoBuf;
using System.Linq;

namespace CycloneDX.Models
{
[ProtoContract]
public class Annotation
public class Annotation : ICloneable
{
[XmlType("subject")]
public class XmlAnnotationSubject
public class XmlAnnotationSubject : ICloneable
{
[XmlAttribute("ref")]
public string Ref { get; set; }

public object Clone()
{
return new XmlAnnotationSubject()
{
Ref = this.Ref
};
}
}

[XmlAttribute("bom-ref")]
Expand Down Expand Up @@ -80,10 +89,24 @@ public DateTime? Timestamp
get => _timestamp;
set { _timestamp = BomUtils.UtcifyDateTime(value); }
}
public bool ShouldSerializeTimestamp() { return Timestamp != null; }


[XmlElement("text")]
[ProtoMember(5)]
public string Text { get; set; }

public bool ShouldSerializeTimestamp() { return Timestamp != null; }

public object Clone()
{
return new Annotation()
{
Annotator = (AnnotatorChoice)this.Annotator.Clone(),
BomRef = this.BomRef,
Subjects = this.Subjects.Select(x => x).ToList(),
Text = this.Text,
Timestamp = this.Timestamp,
XmlSubjects = this.XmlSubjects.Select(x => (XmlAnnotationSubject)x.Clone()).ToList()
};
}
}
}
14 changes: 13 additions & 1 deletion src/CycloneDX.Core/Models/AnnotatorChoice.cs
Original file line number Diff line number Diff line change
Expand Up @@ -15,13 +15,14 @@
// SPDX-License-Identifier: Apache-2.0
// Copyright (c) OWASP Foundation. All Rights Reserved.

using System;
using System.Xml.Serialization;
using ProtoBuf;

namespace CycloneDX.Models
{
[ProtoContract]
public class AnnotatorChoice
public class AnnotatorChoice : ICloneable
{
[XmlElement("organization")]
[ProtoMember(1)]
Expand All @@ -38,5 +39,16 @@ public class AnnotatorChoice
[XmlElement("service")]
[ProtoMember(4)]
public Service Service { get; set; }

public object Clone()
{
return new AnnotatorChoice()
{
Component = (Component)this.Component.Clone(),
Individual = (OrganizationalContact)this.Individual.Clone(),
Organization = (OrganizationalEntity)this.Organization.Clone(),
Service = (Service)this.Service.Clone(),
};
}
}
}
13 changes: 12 additions & 1 deletion src/CycloneDX.Core/Models/AttachedText.cs
Original file line number Diff line number Diff line change
Expand Up @@ -15,13 +15,14 @@
// SPDX-License-Identifier: Apache-2.0
// Copyright (c) OWASP Foundation. All Rights Reserved.

using System;
using System.Xml.Serialization;
using ProtoBuf;

namespace CycloneDX.Models
{
[ProtoContract]
public class AttachedText
public class AttachedText : ICloneable
{
[XmlAttribute("content-type")]
[ProtoMember(1)]
Expand All @@ -34,5 +35,15 @@ public class AttachedText
[XmlText]
[ProtoMember(3)]
public string Content { get; set; }

public object Clone()
{
return new AttachedText()
{
Content = Content,
ContentType = ContentType,
Encoding = Encoding
};
}
}
}
48 changes: 36 additions & 12 deletions src/CycloneDX.Core/Models/Bom.cs
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
using System.Linq;
using System.Text.Json.Serialization;
using System.Xml.Serialization;
using CycloneDX.Models.Vulnerabilities;
using ProtoBuf;

namespace CycloneDX.Models
Expand All @@ -29,7 +30,7 @@ namespace CycloneDX.Models
[SuppressMessage("Microsoft.Usage", "CA2227:CollectionPropertiesShouldBeReadOnly")]
[XmlRoot("bom", IsNullable=false)]
[ProtoContract]
public class Bom
public class Bom : ICloneable
{
[XmlIgnore]
public string BomFormat => "CycloneDX";
Expand Down Expand Up @@ -111,8 +112,7 @@ public int NonNullableVersion
Version = value;
}
}
public bool ShouldSerializeNonNullableVersion() { return Version.HasValue; }


[XmlElement("metadata")]
[ProtoMember(4)]
public Metadata Metadata { get; set; }
Expand All @@ -126,20 +126,17 @@ public int NonNullableVersion
[XmlArrayItem("service")]
[ProtoMember(6)]
public List<Service> Services { get; set; }
public bool ShouldSerializeServices() { return Services?.Count > 0; }


[XmlArray("externalReferences")]
[XmlArrayItem("reference")]
[ProtoMember(7)]
public List<ExternalReference> ExternalReferences { get; set; }
public bool ShouldSerializeExternalReferences() { return ExternalReferences?.Count > 0; }


[XmlArray("dependencies")]
[XmlArrayItem("dependency")]
[ProtoMember(8)]
public List<Dependency> Dependencies { get; set; }
public bool ShouldSerializeDependencies() { return Dependencies?.Count > 0; }


[XmlArray("compositions")]
[XmlArrayItem("composition")]
[ProtoMember(9)]
Expand All @@ -149,24 +146,51 @@ public int NonNullableVersion
[XmlArrayItem("vulnerability")]
[ProtoMember(10)]
public List<Vulnerabilities.Vulnerability> Vulnerabilities { get; set; }
public bool ShouldSerializeVulnerabilities() { return Vulnerabilities?.Count > 0; }

[XmlArray("annotations")]
[XmlArrayItem("annotation")]
[ProtoMember(11)]
public List<Annotation> Annotations { get; set; }
public bool ShouldSerializeAnnotations() { return Annotations?.Count > 0; }

[XmlArray("properties")]
[XmlArrayItem("property")]
[ProtoMember(12)]
public List<Property> Properties { get; set; }
public bool ShouldSerializeProperties() { return Properties?.Count > 0; }

[XmlArray("formulation")]
[XmlArrayItem("formula")]
[ProtoMember(13)]
public List<Formula> Formulation { get; set; }

public bool ShouldSerializeNonNullableVersion() { return Version.HasValue; }
public bool ShouldSerializeServices() { return Services?.Count > 0; }
public bool ShouldSerializeExternalReferences() { return ExternalReferences?.Count > 0; }
public bool ShouldSerializeDependencies() { return Dependencies?.Count > 0; }
public bool ShouldSerializeVulnerabilities() { return Vulnerabilities?.Count > 0; }
public bool ShouldSerializeAnnotations() { return Annotations?.Count > 0; }
public bool ShouldSerializeProperties() { return Properties?.Count > 0; }
public bool ShouldSerializeFormulation() { return Formulation?.Count > 0; }

public object Clone()
{
return new Bom()
{
Annotations = this.Annotations.Select(x => (Annotation)x.Clone()).ToList(),
Components = this.Components.Select(x => (Component)x.Clone()).ToList(),
Compositions = this.Compositions.Select(x => (Composition)x.Clone()).ToList(),
Dependencies = this.Dependencies.Select(x => (Dependency)x.Clone()).ToList(),
ExternalReferences = this.ExternalReferences.Select(x => (ExternalReference)x.Clone()).ToList(),
Formulation = this.Formulation.Select(x => (Formula)x.Clone()).ToList(),
Metadata = (Metadata)this.Metadata.Clone(),
NonNullableVersion = this.NonNullableVersion,
Properties = this.Properties.Select(x => (Property)x.Clone()).ToList(),
SerialNumber = this.SerialNumber,
Services = this.Services.Select(x => (Service)x.Clone()).ToList(),
SpecVersion = this.SpecVersion,
SpecVersionString = this.SpecVersionString,
Version = this.Version,
Vulnerabilities = this.Vulnerabilities.Select(x => (Vulnerability)x.Clone()).ToList(),
};
}
}
}
30 changes: 27 additions & 3 deletions src/CycloneDX.Core/Models/Callstack.cs
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
using System;
using System.Collections.Generic;
using System.Diagnostics.CodeAnalysis;
using System.Linq;
using System.Linq.Expressions;
using System.Text.Json.Serialization;
using System.Xml;
Expand All @@ -28,11 +29,11 @@ namespace CycloneDX.Models
{
[XmlType("callstack")]
[ProtoContract]
public class Callstack
public class Callstack : ICloneable
{
[XmlType("frame")]
[ProtoContract]
public class Frame
public class Frame : ICloneable
{
[XmlElement("package")]
[ProtoMember(1)]
Expand All @@ -50,7 +51,6 @@ public class Frame
[XmlArrayItem("parameter")]
[ProtoMember(4)]
public List<string> Parameters { get; set; }
public bool ShouldSerializeParameters() { return Parameters?.Count > 0; }

[XmlElement("line")]
[ProtoMember(5)]
Expand All @@ -63,11 +63,35 @@ public class Frame
[XmlElement("fullFilename")]
[ProtoMember(7)]
public string FullFilename { get; set; }

public bool ShouldSerializeParameters() { return Parameters?.Count > 0; }

public object Clone()
{
return new Frame()
{
Column = this.Column,
FullFilename = this.FullFilename,
Function = this.Function,
Line = this.Line,
Module = this.Module,
Package = this.Package,
Parameters = this.Parameters.Select(x => x).ToList()
};
}
}

[XmlArray("frames")]
[XmlArrayItem("frame")]
[ProtoMember(1)]
public List<Frame> Frames { get; set; }

public object Clone()
{
return new Callstack()
{
Frames = this.Frames.Select(x => (Frame)x.Clone()).ToList()
};
}
}
}
13 changes: 12 additions & 1 deletion src/CycloneDX.Core/Models/Command.cs
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
using System;
using System.Collections.Generic;
using System.Diagnostics.CodeAnalysis;
using System.Linq;
using System.Text.Json.Serialization;
using System.Xml.Serialization;
using ProtoBuf;
Expand All @@ -26,7 +27,7 @@ namespace CycloneDX.Models
{
[XmlType("command")]
[ProtoContract]
public class Command
public class Command : ICloneable
{
[XmlElement("executed")]
[ProtoMember(1)]
Expand All @@ -36,6 +37,16 @@ public class Command
[XmlArrayItem("property")]
[ProtoMember(2)]
public List<Property> Properties { get; set; }

public bool ShouldSerializeProperties() { return Properties?.Count > 0; }

public object Clone()
{
return new Command()
{
Executed = this.Executed,
Properties = this.Properties.Select(x => (Property)x.Clone()).ToList()
};
}
}
}
15 changes: 14 additions & 1 deletion src/CycloneDX.Core/Models/Commit.cs
Original file line number Diff line number Diff line change
Expand Up @@ -15,13 +15,14 @@
// SPDX-License-Identifier: Apache-2.0
// Copyright (c) OWASP Foundation. All Rights Reserved.

using System;
using System.Xml.Serialization;
using ProtoBuf;

namespace CycloneDX.Models
{
[ProtoContract]
public class Commit
public class Commit : ICloneable
{
[XmlElement("uid")]
[ProtoMember(1)]
Expand All @@ -42,5 +43,17 @@ public class Commit
[XmlElement("message")]
[ProtoMember(5)]
public string Message { get; set; }

public object Clone()
{
return new Commit()
{
Author = (IdentifiableAction)this.Author.Clone(),
Committer = (IdentifiableAction)this.Committer.Clone(),
Message = this.Message,
Uid = this.Uid,
Url = this.Url,
};
}
}
}
Loading

0 comments on commit c93e130

Please sign in to comment.