Skip to content

Commit

Permalink
Fix unsupported exception when checking the Length property on Stream…
Browse files Browse the repository at this point in the history
…s created by ZipArchiveArtifact (#2767)

* fixen

* release notes
  • Loading branch information
scottoneil-ms committed Jan 24, 2024
1 parent 8e49ab2 commit 77366a6
Show file tree
Hide file tree
Showing 3 changed files with 32 additions and 7 deletions.
1 change: 1 addition & 0 deletions ReleaseHistory.md
Expand Up @@ -6,6 +6,7 @@
* DEP: Update `Microsoft.Data.SqlClient` reference from 2.1.2 to 2.1.7 in `WorkItems` and `Sarif.Multitool.Library` to resolve [CVE-2024-0056](https://github.com/advisories/GHSA-98g6-xh36-x2p7).
* DEP: Update `System.Data.SqlClient` reference from 4.8.5 to 4.8.6 in `WorkItems` to resolve [CVE-2024-0056](https://github.com/advisories/GHSA-98g6-xh36-x2p7).
* BUG: Update `Stack.Create` method to populate missing `PhysicalLocation` instances when stack frames reference relative file paths.
* BUG: Fix `UnsupportedOperationException` in `ZipArchiveArtifact`.
* NEW: Add `IsBinary` property to `IEnumeratedArtifact` and implement the property in `ZipArchiveArtifact`.
* PRF: Change default `max-file-size-in-kb` parameter to 10 megabytes.
* PRF: Add support for efficiently peeking into non-seekable streams for binary/text categorization.
Expand Down
1 change: 0 additions & 1 deletion src/Sarif/PeekableStream.cs
Expand Up @@ -52,7 +52,6 @@ public override int Read(byte[] buffer, int offset, int count)
return underlyingStream.Read(buffer, offset, count);
}


// This code relies upon delivering partial reads for correctness. Let's say the caller knows the stream length is 1 MB,
// and we have a 1 KB peekability window/buffer. If they do a read with count=1000000, we will return a 1 KB read.
// Afterwards, cursor will be exactly equal to buffer.Length. A second count=1MB Read() would detect that, transition
Expand Down
37 changes: 31 additions & 6 deletions src/Sarif/ZipArchiveArtifact.cs
Expand Up @@ -94,8 +94,24 @@ public byte[] Bytes
string extension = Path.GetExtension(Uri.ToString());
if (this.binaryExtensions.Contains(extension))
{
this.bytes = new byte[Stream.Length];
Stream.Read(this.bytes, 0, this.bytes.Length);
// The underlying System.IO.Compression.DeflateStream throws on reads to get_Length.
using var ms = new MemoryStream((int)SizeInBytes.Value);
this.Stream.CopyTo(ms);

byte[] memStreamBuffer = ms.GetBuffer();
if (memStreamBuffer.Length == ms.Position)
{
// We might have succeeded in exactly sizing the MemoryStream. In that case, we can just use it.
this.bytes = memStreamBuffer;
}
else
{
// No luck. Have to take a copy to align the buffers.
ms.Position = 0;
this.bytes = new byte[ms.Length];

ms.Read(this.bytes, 0, this.bytes.Length);
}
}
else
{
Expand All @@ -113,18 +129,27 @@ public byte[] Bytes
{
get
{
if (this.contents != null)
{
return this.contents.Length;
}

if (this.bytes != null)
{
return this.bytes.Length;
}

lock (this.archive)
{
if (this.entry != null)
{
return this.entry.Length;
}

return this.contents != null
? this.contents.Length
: this.bytes.Length;
}

return null;
}

set => throw new NotImplementedException();
}
}
Expand Down

0 comments on commit 77366a6

Please sign in to comment.