Jumoo / uSync.Complete.Issues

Public Issue tracker and roadmap for uSync.Complete
https://jumoo.co.uk/usync/complete/
2 stars 1 forks source link

Could not find a part of the path Error when uploading and extracting a SyncPack #117

Closed tompipe closed 3 years ago

tompipe commented 3 years ago

Describe the bug When uploading a SyncPack, an error seems to occur when extracting the ziparchive.

Exception
System.IO.DirectoryNotFoundException: Could not find a part of the path 'C:\src\UmbracoProject.Web\App_Data\TEMP\uSync\exports\8ed05c13-a2db-45f9-87d4-9b799c567aef\uSync\'.
   at System.IO.__Error.WinIOError(Int32 errorCode, String maybeFullPath)
   at System.IO.FileStream.Init(String path, FileMode mode, FileAccess access, Int32 rights, Boolean useRights, FileShare share, Int32 bufferSize, FileOptions options, SECURITY_ATTRIBUTES secAttrs, String msgPath, Boolean bFromProxy, Boolean useLongPath, Boolean checkHost)
   at System.IO.FileStream..ctor(String path, FileMode mode, FileAccess access, FileShare share)
   at System.IO.Compression.ZipFileExtensions.ExtractToFile(ZipArchiveEntry source, String destinationFileName, Boolean overwrite)
   at uSync.Expansions.Core.Physical.SyncPackFileService.SafeUnzip(String zipfile, String target)
   at uSync.Expansions.Core.Physical.SyncPackFileService.UnpackExport(String zipfile)
   at uSync.Exporter.Services.SyncExporterService.UnpackExport(Guid id)
   at uSync.Exporter.Controllers.uSyncNuExporterApiController.<UploadFile>d__39.MoveNext()

I've tracked it down to line 429 of the SyncPackFileService SafeUnzip method. It fails when a ZipArchiveEntry is for a folder itself, and not a file, then it fails when attempting to call the ExtractToFile method.

In the System.IO.Compression.ExtractToDirectory extension method, there are checks on the entry filename and data length to prevent calling ExtractToFile for directories.

// Decompiled with JetBrains decompiler
// Type: System.IO.Compression.ZipFileExtensions
// Assembly: System.IO.Compression.FileSystem, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
// MVID: 09CD476E-F34D-45A8-A85F-2FABBE2EBC6B
// Assembly location: C:\Windows\Microsoft.NET\Framework\v4.0.30319\System.IO.Compression.FileSystem.dll
public static void ExtractToDirectory(this ZipArchive source, string destinationDirectoryName)
{
  if (source == null)
    throw new ArgumentNullException(nameof (source));
  string path1 = destinationDirectoryName != null ? Directory.CreateDirectory(destinationDirectoryName).FullName : throw new ArgumentNullException(nameof (destinationDirectoryName));
  if (!LocalAppContextSwitches.DoNotAddTrailingSeparator)
  {
    int length = path1.Length;
    if (length != 0 && (int) path1[length - 1] != (int) Path.DirectorySeparatorChar)
      path1 += Path.DirectorySeparatorChar.ToString();
  }
  foreach (ZipArchiveEntry entry in source.Entries)
  {
    string fullPath = Path.GetFullPath(Path.Combine(path1, entry.FullName));
    if (!fullPath.StartsWith(path1, StringComparison.OrdinalIgnoreCase))
      throw new IOException(SR.GetString("IO_ExtractingResultsInOutside"));
    if (Path.GetFileName(fullPath).Length == 0)
    {
      if (entry.Length != 0L)
        throw new IOException(SR.GetString("IO_DirectoryNameWithData"));
      Directory.CreateDirectory(fullPath);
    }
    else
    {
      Directory.CreateDirectory(Path.GetDirectoryName(fullPath));
      entry.ExtractToFile(fullPath, false);
    }
  }
}

Adding similar checks to SafeUnzip would prevent the error, alternatively calling the ExtractToDirectory extension method might be a better fix, as that handles the mitigation for the change of path seperator in .NET Framework 4.6.1

Version (please complete the following information):

To Reproduce Steps to reproduce the behavior:

  1. Create a SyncPack
  2. Navigate to settings/uSync8/dashboard/exporter
  3. Click import sync pack
  4. Upload file
  5. Button should change to an X and an error similar to above is reported in umbraco log viewer

Expected behavior Syncpack should be uploaded, extracted, and the changes report presented

KevinJump commented 3 years ago

hi tom, if possible can you send me the sync pack you are using here ? kevin@jumoo.co.uk .

KevinJump commented 3 years ago

Hi Tom, exactly as you say - looks like the sync pack has ended up with directory entries in it and we don't copy with them. v8.10.1 fixes this. by using the ExtractToDirectory method (i think at one point we did it with ExtractToFile so we could update progress - but we don't anymore as unzipping is often fast.)