Skip to content

Commit 04e50b0

Browse files
committed
fix: replace System.Text.Json with regex-based approach for MSBuild task compatibility
The EnsureSbomVersionField inline task was using System.Text.Json which is not available in all MSBuild contexts (particularly when MSBuild runs on .NET Framework). This change replaces the JSON parsing with a simple regex-based string manipulation approach that only depends on System.Text and System.Text.RegularExpressions, which are available in all .NET Framework and .NET Core versions. Fixes compilation error: CS0234 'Json' does not exist in namespace 'System.Text'
1 parent e7ad630 commit 04e50b0

File tree

1 file changed

+31
-24
lines changed

1 file changed

+31
-24
lines changed

src/CycloneDX.MSBuild/build/CycloneDX.MSBuild.targets

Lines changed: 31 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -152,44 +152,51 @@
152152
</ParameterGroup>
153153
<Task>
154154
<Using Namespace="System.IO" />
155-
<Using Namespace="System.Text.Json" />
155+
<Using Namespace="System.Text" />
156+
<Using Namespace="System.Text.RegularExpressions" />
156157
<Code Type="Fragment" Language="cs">
157158
<![CDATA[
158159
try
159160
{
160-
var jsonString = File.ReadAllText(SbomPath);
161-
var options = new JsonDocumentOptions { AllowTrailingCommas = true };
162-
using var document = JsonDocument.Parse(jsonString, options);
163-
var root = document.RootElement;
161+
var jsonContent = File.ReadAllText(SbomPath);
164162
165-
// Check if version field exists
166-
if (!root.TryGetProperty("version", out _))
163+
// Simple check if version field already exists using regex
164+
// Look for "version" field at the root level (after opening brace, before other fields)
165+
var versionPattern = @"^\s*\{\s*""version""\s*:";
166+
if (Regex.IsMatch(jsonContent, versionPattern, RegexOptions.Multiline))
167167
{
168-
// Create a new JSON object with version field
169-
using var outputStream = new MemoryStream();
170-
using (var writer = new Utf8JsonWriter(outputStream, new JsonWriterOptions { Indented = true }))
171-
{
172-
writer.WriteStartObject();
173-
174-
// Write version field first
175-
writer.WriteNumber("version", 1);
168+
Log.LogMessage(MessageImportance.Low, "[CycloneDX] SBOM already has version field");
169+
return true;
170+
}
176171
177-
// Copy all existing properties from the already-parsed document
178-
foreach (var property in root.EnumerateObject())
179-
{
180-
property.WriteTo(writer);
181-
}
172+
// Version field doesn't exist, add it
173+
// Find the opening brace and insert version field right after it
174+
var insertPattern = @"^(\s*\{)\s*$";
175+
var replacement = "$1\n \"version\": 1,";
176+
var updatedContent = Regex.Replace(jsonContent, insertPattern, replacement, RegexOptions.Multiline);
182177
183-
writer.WriteEndObject();
178+
// If the pattern didn't match (single-line opening), try a simpler approach
179+
if (updatedContent == jsonContent)
180+
{
181+
// Handle compact JSON: { "bomFormat": ... }
182+
if (jsonContent.TrimStart().StartsWith("{"))
183+
{
184+
var firstBraceIndex = jsonContent.IndexOf('{');
185+
updatedContent = jsonContent.Substring(0, firstBraceIndex + 1) +
186+
"\n \"version\": 1," +
187+
jsonContent.Substring(firstBraceIndex + 1);
184188
}
189+
}
185190
186-
// Write back to file
187-
File.WriteAllBytes(SbomPath, outputStream.ToArray());
191+
// Write back to file if content changed
192+
if (updatedContent != jsonContent)
193+
{
194+
File.WriteAllText(SbomPath, updatedContent, Encoding.UTF8);
188195
Log.LogMessage(MessageImportance.Low, "[CycloneDX] Added version field to SBOM");
189196
}
190197
else
191198
{
192-
Log.LogMessage(MessageImportance.Low, "[CycloneDX] SBOM already has version field");
199+
Log.LogWarning("[CycloneDX] Could not add version field - unexpected JSON format");
193200
}
194201
}
195202
catch (Exception ex)

0 commit comments

Comments
 (0)