SevenZipSharp icon indicating copy to clipboard operation
SevenZipSharp copied to clipboard

Exception when calling CompressDirectory with searchPattern that returns empty file collection

Open kborowinski opened this issue 2 years ago • 0 comments

@squid-box SevenZipSharp throws an exception when calling CompressDirectory with flag IncludeEmptyDirectories set to false and an searchPattern that returns empty file collection:

Repro with PowerShell:

Add-Type -AssemblyName .\SevenZipSharp.dll
$c = [SevenZip.SevenZipCompressor]::new()
$c.IncludeEmptyDirectories = $false
mkdir test
cd test
mkdir test2
cd test2
echo test > test.ini
cd /
$c.CompressDirectory('C:\test', 'C:\test.7z', $null, '*.config', $true)
MethodInvocationException: Exception calling "CompressDirectory" with "5" argument(s): "Index was out of range. Must be non-negative and less than the size of the collection. (Parameter 'index')"

Error details:

PSMessageDetails      :
Exception             : System.Management.Automation.MethodInvocationException: Exception calling "CompressDirectory" with "5" argument(s): "Index was out of range. Must be non-negative
                        and less than the size of the collection. (Parameter 'index')"
                         ---> System.ArgumentOutOfRangeException: Index was out of range. Must be non-negative and less than the size of the collection. (Parameter 'index')
                           at SevenZip.SevenZipBase.ThrowException(CallbackBase handler, Exception[] e)
                           at SevenZip.SevenZipCompressor.CompressFilesEncrypted(Stream archiveStream, Int32 commonRootLength, String password, String[] fileFullNames)
                           at SevenZip.SevenZipCompressor.CompressDirectory(String directory, Stream archiveStream, String password, String searchPattern, Boolean recursion)
                           at SevenZip.SevenZipCompressor.CompressDirectory(String directory, String archiveName, String password, String searchPattern, Boolean recursion)
                           at CallSite.Target(Closure, CallSite, Object, String, String, Object, String, Boolean)
                           --- End of inner exception stack trace ---
                           at System.Management.Automation.ExceptionHandlingOps.ConvertToMethodInvocationException(Exception exception, Type typeToThrow, String methodName, Int32
                        numArgs, MemberInfo memberInfo)
                           at CallSite.Target(Closure, CallSite, Object, String, String, Object, String, Boolean)
                           at System.Dynamic.UpdateDelegates.UpdateAndExecute6[T0,T1,T2,T3,T4,T5,TRet](CallSite site, T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5)
                           at System.Management.Automation.Interpreter.DynamicInstruction`7.Run(InterpretedFrame frame)
                           at System.Management.Automation.Interpreter.EnterTryCatchFinallyInstruction.Run(InterpretedFrame frame)
TargetObject          :
CategoryInfo          : NotSpecified: (:) [], MethodInvocationException
FullyQualifiedErrorId : ArgumentOutOfRangeException
ErrorDetails          :
InvocationInfo        : System.Management.Automation.InvocationInfo
ScriptStackTrace      : at <ScriptBlock>, <No file>: line 1
PipelineIterationInfo : {}

Explanation:

  1. CompressDirectory method calls CompressFilesEncrypted with an empty files collection, since no files with*.config extension where found in the directory
  2. CompressFilesEncrypted calls ProduceFileInfoArray with empty fileFullNames collection
  3. And that causes exception in ProduceFileInfoArray on line 581 when getting the commonRoot substring, since it's trying to index empty files array

kborowinski avatar Dec 04 '23 10:12 kborowinski