Conversation
SharpHDiffPatch -> SharpHPatchZ
Attempt to implement a thread-safe Merged Stream Wrapper for Read/Write operations. Warning: Most of the Code for the reader are vibe-coded. So, need to check it further.
+ Struct type adjustment inside DirectoryPatchMetadata
+ Use UnmanagedArray<T> for some input-output ref lists instead of a direct array pointer
+ Fix CreateUnmanagedInt64List and CreateUnmanagedInt64As32List reading on backed numbers
+ Add extern functions:
- shpz_get_last_errorA
- shpz_get_last_errorW
- shpz_patch_from_filepath
- shpz_patch_from_FILE
+ Make some string arguments in extern functions auto-detect the encoding of the string
- shpz_read_header_signature_string
- shpz_init_from_filepath
- shpz_patch_from_filepath
+ Make the ExceptionHelper throw functions returns the Exception instead of throwing within
+ Add implicit cast for Utf16UnmanagedString and NativeStringW
+ Remove unnecessary type size check on UnmanagedArray<T>.GetSpan()
+ Use numbered error code on ExceptionHelper instead of flags
+ Add callback allocation check on ProgressCallback to avoit ExecutionEngineException due to attempt on calling null callback.
Use .NET Framework 4.7.2 for testing the lowest version of .NET to be supported
| #if NET6_0_OR_GREATER | ||
| copyOverTcs.SetCanceled(token); | ||
| #else | ||
| copyOverTcs.SetCanceled(); | ||
| #endif |
This comment was marked as outdated.
This comment was marked as outdated.
Sorry, something went wrong.
+ Reenable PrefetchedReadStream for Zstd
|
Review the following changes in direct dependencies. Learn more about Socket for GitHub.
|
|
All alerts resolved. Learn more about Socket for GitHub. This PR previously contained dependency changes with security issues that have been resolved, removed, or ignored. |
For compatibility testing. As per Microsoft documentation, .NET Standard should support down to .NET Framework 4.6.1 https://learn.microsoft.com/en-us/dotnet/standard/net-standard?tabs=net-standard-2-0
+ HPatch.TryGetHDiff13PatchMetadata (Extern: shpz_util_get_hdiff13_patch_metadata) + HPatch.TryGetHDiff19DirectoryPatchMetadata (Extern: shpz_util_get_hdiff19_patch_metadata)
| catch (OperationCanceledException) when (token.IsCancellationRequested) | ||
| { | ||
| #if NET6_0_OR_GREATER | ||
| copyOverTcs.SetCanceled(token); |
There was a problem hiding this comment.
Bug: The corePatcherThread cancellation handler signals the wrong TaskCompletionSource, copyOverTcs instead of corePatcherTcs, causing a hang or an unhandled InvalidOperationException during cancellation.
Severity: HIGH
Suggested Fix
In the catch (OperationCanceledException) block for corePatcherThread in HDiff13DerivedPatcher.cs, change the calls from copyOverTcs.SetCanceled() to corePatcherTcs.SetCanceled(). This ensures the correct task is marked as canceled.
Prompt for AI Agent
Review the code at the location below. A potential bug has been identified by an AI
agent. Verify if this is a real issue. If it is, propose a fix; if not, explain why it's
not valid.
Location: SharpHPatchZ/Patch/HDiff13DerivedPatcher.cs#L80
Potential issue: In the `corePatcherThread`, the `catch` block for
`OperationCanceledException` incorrectly signals `copyOverTcs.SetCanceled()` instead of
`corePatcherTcs.SetCanceled()`. This leaves the `corePatcherTcs` task incomplete. As a
result, the main thread, waiting on `Task.WhenAll`, will hang. If the `copyOverThread`
has already completed its task, attempting to cancel the already-completed `copyOverTcs`
will throw an `InvalidOperationException`, leading to an unhandled exception that
terminates the process.
Also affects:
SharpHPatchZ/Patch/HDiff13DerivedPatcher.cs:83~83
|
|
||
| public void Dispose() | ||
| { | ||
| _lifetimeLock.EnterWriteLock(); |
There was a problem hiding this comment.
Bug: The Dispose() method in RandomMergedStreamWrapper is not idempotent. A second call will throw an ObjectDisposedException because it tries to use a lock that was disposed on the first call.
Severity: MEDIUM
Suggested Fix
Move the idempotency check if (Interlocked.Exchange(ref _disposed, 1) == 1) return; to be the first statement in the Dispose() method, before the _lifetimeLock.EnterWriteLock() call. This will ensure subsequent calls exit immediately without causing an exception.
Prompt for AI Agent
Review the code at the location below. A potential bug has been identified by an AI
agent. Verify if this is a real issue. If it is, propose a fix; if not, explain why it's
not valid.
Location: SharpHPatchZ/IO/Reader/RandomMergedStreamWrapper.cs#L141
Potential issue: The `Dispose()` method in `RandomMergedStreamWrapper` is not
idempotent, violating the `IDisposable` contract. On the first call, it acquires a
`ReaderWriterLockSlim` and disposes of it in the `finally` block. If `Dispose()` is
called a second time on the same instance, it attempts to acquire the lock again via
`_lifetimeLock.EnterWriteLock()`. Since the lock has already been disposed, this call
throws an `ObjectDisposedException`. The idempotency check is placed after the lock
acquisition, so it is never reached on the second call.
- shpz_util_get_hdiff13_patch_metadata -> shpz_util_get_patch_metadata - shpz_util_get_hdiff19_patch_metadata -> shpz_util_get_directory_patch_metadata
WARNING: Fully Vibe-coded. Further test is required
Btw, 6 🤷 7
|
|
||
| Parallel.For(0, count, new ParallelOptions | ||
| { | ||
| MaxDegreeOfParallelism = (int)options.ParallelThreads |
There was a problem hiding this comment.
Bug: CopySimilarFilesContext.RunCopy() passes options.ParallelThreads directly to Parallel.For, which crashes if the value is 0. This occurs when PatchOptions is default-initialized.
Severity: HIGH
Suggested Fix
In CopySimilarFilesContext.RunCopy(), validate options.ParallelThreads before passing it to Parallel.For. Reuse the logic from CorePatcher.GetWorkerCount() to safely convert a value of 0 to a valid thread count, like Environment.ProcessorCount.
Prompt for AI Agent
Review the code at the location below. A potential bug has been identified by an AI
agent. Verify if this is a real issue. If it is, propose a fix; if not, explain why it's
not valid.
Location: SharpHPatchZ/Patch/HDiff13DerivedPatcher.CopySimilarFilesContext.cs#L34
Potential issue: When a directory patch is initiated via the unmanaged API with `null`
options, a default `PatchOptions` object is created where `ParallelThreads` is 0. This
value is passed directly to `Parallel.For`'s `MaxDegreeOfParallelism` in
`CopySimilarFilesContext.RunCopy()`, causing an `ArgumentOutOfRangeException`. Unlike
`CorePatcher`, this code path lacks a guard to handle the zero value by converting it to
a valid number of threads, such as `Environment.ProcessorCount`. This leads to a crash
when patching directories that contain similar files.
TODO: Description
Benchmark Result
Test: Single file, LZMA2 compressed
Test: Directory, LZMA2 compressed
Test: Single file, LZMA2 compressed - Native (Result: 25 ms)
Test: Directory, LZMA compressed - Native (Result: 4.906 s)