Skip to content

ZipFile.ExtractToDirectory failing with "The filename, directory name, or volume label syntax is incorrect." (works in SharpZipLib) #67201

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
smoothdeveloper opened this issue Mar 27, 2022 · 83 comments
Assignees
Labels
area-System.IO.Compression good first issue Issue should be easy to implement, good for first-time contributors

Comments

@smoothdeveloper
Copy link

Description

I have some code using System.IO.Compression:

ZipFile.ExtractToDirectory(archive, Path.Combine(directory.FullName, "groove-v1.0.0-midionly"))

Reproduction Steps

putting this in a .fsx file and running it with dotnet fsi:

#r "nuget: System.IO.Compression"
open System
open System.IO
open System.IO.Compression
open System.Net.Http
let directory = DirectoryInfo __SOURCE_DIRECTORY__
let archive = Path.Combine(__SOURCE_DIRECTORY__, "groove-v1.0.0-midionly.zip")
do
    let uri = "https://storage.googleapis.com/magentadata/datasets/groove/groove-v1.0.0-midionly.zip"
    use client = new HttpClient(Timeout = TimeSpan.FromMinutes 30)
    use resp = client.Send(new HttpRequestMessage(RequestUri=Uri uri))
    use stream = resp.Content.ReadAsStream()
    use file = File.OpenWrite(archive)
    stream.CopyTo(file)
//let fz = ICSharpCode.SharpZipLib.Zip.FastZip()
//fz.ExtractZip(archive, Path.Combine(directory.FullName, filesetName), "")
// dotnet one fails one the groove dataset.
ZipFile.ExtractToDirectory(archive, Path.Combine(directory.FullName, "groove-v1.0.0-midionly"))

I tried on macos, and it doesn't seem to fail, so maybe it is platform dependent.

Expected behavior

I wish it would work, extracting without an exception.

Actual behavior

System.IO.IOException: The filename, directory name, or volume label syntax is incorrect. : 'C:\dev\src\github.com\smoothdeveloper\zcore-midi-fs\demo\groove-v1.0.0-midionly\groove\drummer8\session2\Icon
'
at Microsoft.Win32.SafeHandles.SafeFileHandle.CreateFile(String fullPath, FileMode mode, FileAccess access, FileShare share, FileOptions options)
at Microsoft.Win32.SafeHandles.SafeFileHandle.Open(String fullPath, FileMode mode, FileAccess access, FileShare share, FileOptions options, Int64 preallocationSize)
at System.IO.Strategies.OSFileStreamStrategy..ctor(String path, FileMode mode, FileAccess access, FileShare share, FileOptions options, Int64 preallocationSize)
at System.IO.Compression.ZipFileExtensions.ExtractToFile(ZipArchiveEntry source, String destinationFileName, Boolean overwrite)
at System.IO.Compression.ZipFileExtensions.ExtractToDirectory(ZipArchive source, String destinationDirectoryName, Boolean overwriteFiles)
at System.IO.Compression.ZipFile.ExtractToDirectory(String sourceArchiveFileName, String destinationDirectoryName, Encoding entryNameEncoding, Boolean overwriteFiles)
at <StartupCode$FSI_0003>.$FSI_0003.main@() in

Regression?

No response

Known Workarounds

I am using FastZip class from ICSharpCode.SharpZipLib.Zip to work around the issue.

Configuration

Welcome to F# Interactive for .NET Core in Visual Studio. To execute code, either
  1. Use 'Send to Interactive' (Alt-Enter or right-click) from an F# script. The F# Interactive process will
     use any global.json settings associated with that script.
  2. Press 'Enter' to start. The F# Interactive process will use default settings.
> 

Microsoft (R) F# Interactive version 12.0.2.0 for F# 6.0
Copyright (c) Microsoft Corporation. All Rights Reserved.
  • Windows 11 x64
  • VS2022 preview
  • dotnet 7 preview 2

Other information

No response

@ghost
Copy link

ghost commented Mar 27, 2022

Tagging subscribers to this area: @dotnet/area-system-io-compression
See info in area-owners.md if you want to be subscribed.

Issue Details

Description

I have some code using System.IO.Compression:

ZipFile.ExtractToDirectory(archive, Path.Combine(directory.FullName, "groove-v1.0.0-midionly"))

Reproduction Steps

putting this in a .fsx file and running it with dotnet fsi:

#r "nuget: System.IO.Compression"
open System
open System.IO
open System.IO.Compression
open System.Net.Http
let directory = DirectoryInfo __SOURCE_DIRECTORY__
let archive = Path.Combine(__SOURCE_DIRECTORY__, "groove-v1.0.0-midionly.zip")
do
    let uri = "https://storage.googleapis.com/magentadata/datasets/groove/groove-v1.0.0-midionly.zip"
    use client = new HttpClient(Timeout = TimeSpan.FromMinutes 30)
    use resp = client.Send(new HttpRequestMessage(RequestUri=Uri uri))
    use stream = resp.Content.ReadAsStream()
    use file = File.OpenWrite(archive)
    stream.CopyTo(file)
//let fz = ICSharpCode.SharpZipLib.Zip.FastZip()
//fz.ExtractZip(archive, Path.Combine(directory.FullName, filesetName), "")
// dotnet one fails one the groove dataset.
ZipFile.ExtractToDirectory(archive, Path.Combine(directory.FullName, "groove-v1.0.0-midionly"))

I tried on macos, and it doesn't seem to fail, so maybe it is platform dependent.

Expected behavior

I wish it would work, extracting without an exception.

Actual behavior

System.IO.IOException: The filename, directory name, or volume label syntax is incorrect. : 'C:\dev\src\github.com\smoothdeveloper\zcore-midi-fs\demo\groove-v1.0.0-midionly\groove\drummer8\session2\Icon
'
at Microsoft.Win32.SafeHandles.SafeFileHandle.CreateFile(String fullPath, FileMode mode, FileAccess access, FileShare share, FileOptions options)
at Microsoft.Win32.SafeHandles.SafeFileHandle.Open(String fullPath, FileMode mode, FileAccess access, FileShare share, FileOptions options, Int64 preallocationSize)
at System.IO.Strategies.OSFileStreamStrategy..ctor(String path, FileMode mode, FileAccess access, FileShare share, FileOptions options, Int64 preallocationSize)
at System.IO.Compression.ZipFileExtensions.ExtractToFile(ZipArchiveEntry source, String destinationFileName, Boolean overwrite)
at System.IO.Compression.ZipFileExtensions.ExtractToDirectory(ZipArchive source, String destinationDirectoryName, Boolean overwriteFiles)
at System.IO.Compression.ZipFile.ExtractToDirectory(String sourceArchiveFileName, String destinationDirectoryName, Encoding entryNameEncoding, Boolean overwriteFiles)
at <StartupCode$FSI_0003>.$FSI_0003.main@() in

Regression?

No response

Known Workarounds

I am using FastZip class from ICSharpCode.SharpZipLib.Zip to work around the issue.

Configuration

Welcome to F# Interactive for .NET Core in Visual Studio. To execute code, either
  1. Use 'Send to Interactive' (Alt-Enter or right-click) from an F# script. The F# Interactive process will
     use any global.json settings associated with that script.
  2. Press 'Enter' to start. The F# Interactive process will use default settings.
> 

Microsoft (R) F# Interactive version 12.0.2.0 for F# 6.0
Copyright (c) Microsoft Corporation. All Rights Reserved.
  • Windows 11 x64
  • VS2022 preview
  • dotnet 7 preview 2

Other information

No response

Author: smoothdeveloper
Assignees: -
Labels:

area-System.IO.Compression

Milestone: -

@danmoseley
Copy link
Member

C:\dev\src\github.com\smoothdeveloper\zcore-midi-fs\demo\groove-v1.0.0-midionly\groove\drummer8\session2\Icon
'

Looks like there's a newline at the end of the path. That would cause this exception, too.

@danmoseley
Copy link
Member

danmoseley commented Mar 27, 2022

Newlines in paths are valid in POSIX (although wierd). Looking at SharpZipLib, it does some cleaning of paths before writing them in Windows

https://github.com/icsharpcode/SharpZipLib/blob/cc8dd78ed989888f6685da4cc009c529158738b4/src/ICSharpCode.SharpZipLib/Zip/WindowsNameTransform.cs#L29-L37
https://github.com/icsharpcode/SharpZipLib/blob/cc8dd78ed989888f6685da4cc009c529158738b4/src/ICSharpCode.SharpZipLib/Zip/WindowsNameTransform.cs#L210

In our code see essentially no sanitization. I notice that this sanitization idea was discussed here #15938 (comment) and rejected, but nobody felt strongly. The idea was you could instead enumerate the zip entries manually and write them out with your own names. I think it is more useful for ExtractToDirectory to sanitize with underscore replacements, as 7zip and SharpZipLib behavior suggests. If someone didn't like the sanitization scheme, they could do it manually rather than using ExtractToDirectory.

The work required is

  1. add a test zip file into runtime-assets that contains files with these various characters that should be sanitized. You might need to use Linux, such as WSL, to be able to create this zip - not sure. (As a test, try extracting it with sharpziplib or possibly 7zip and verify that it extracts correctly, using underscores in place of each special character)
  2. after that PR is merged, wait a few hours for a PR to appear like this one that updates this repo to consume it.
  3. add tests similar to this one, but that succeed rather than throw. verify they fail.
  4. make tests pass by sanitizing probably here
    private static string GetFileName_Windows(string path)
    using the same rules as SharpZipLib. you might need to fix some pre existing tests that were previously expecting this to fail.
  5. put up the changes as a PR into this repo.

@danmoseley danmoseley added good first issue Issue should be easy to implement, good for first-time contributors help wanted [up-for-grabs] Good issue for external contributors labels Mar 27, 2022
@danmoseley
Copy link
Member

@smoothdeveloper any interest in offering a PR for this?

@oguzeldereli1
Copy link
Contributor

@danmoseley I would like to help, but this is my first time. Could you point me in the right direction to start?

@danmoseley
Copy link
Member

@Danyy427 for sure, I've broken out the steps above. First thing is to make a test zip and put it in the runtime-assets repo.

Before you get started, let's just double check with the owners of this area: @dotnet/area-system-io-compression that they support this change.

@danmoseley
Copy link
Member

Meantime, you can follow the 'getting started' steps in this repo (linked from the README) to clone, build, and get tests passing for this repo without any changes.

@oguzeldereli1
Copy link
Contributor

oguzeldereli1 commented Mar 27, 2022

@danmoseley the original question is in F# but I may write code in C#, right? Also if I understood correctly I am going to make some tests where the characters that need sanitization are being used, and upload them to runtime-assets?

Sure will read the "getting started"

@danmoseley
Copy link
Member

Yes we exclusively use C# in this repo (except when testing VB or F# scenarios.)

Yes, you will want to create a little zip file that has all the wierd characters in its file names listed here. You will need to figure out how to do that, and it may involve (if you're on Windows) using Linux (via WSL) and the Unix 'zip' utility, for example.
https://github.com/icsharpcode/SharpZipLib/blob/cc8dd78ed989888f6685da4cc009c529158738b4/src/ICSharpCode.SharpZipLib/Zip/WindowsNameTransform.cs#L29

@smoothdeveloper
Copy link
Author

@danmoseley, thanks for the feedback on confirming the issue and the reason of it surfacing, sharing great insights.

I can't help with a fix for it but thanks for the offer; I am also happy to see @danny427 is going to give it a try based on your guidance, and confirm it doesn't matter I was using it from F# code for purpose of the fix.

Thanks all!

@oguzeldereli1
Copy link
Contributor

oguzeldereli1 commented Mar 27, 2022

@danmoseley I made that zip file with some test files/folders inside it. However, it is not possible to put '\0' in a filename even in Linux/UNIX. Should I attempt to write directly to my hard drive to put a null character or is it overkill/not necessary?

Update: I have just tested extracting the said zip file with 7zip and indeed all of the characters are replaced with underscores.

@danmoseley
Copy link
Member

danmoseley commented Mar 27, 2022

I wouldn't bother with \0 if it isn't obvious how someone would make such things.

The concept here is that a zip that extracts successfully on Unix should extract successfully on Windows. It's not a goal to extract random synthetic zips.

@oguzeldereli1
Copy link
Contributor

oguzeldereli1 commented Mar 27, 2022

@danmoseley Ok, then how would I go about uploading the zip? Do I make a clone of runtime-assets, add the zip file and put up a pull request?

@danmoseley
Copy link
Member

@Danyy427 exactly, once you have tested it by extracting it yourself with sharpziplib and verified that it produces the same content you put in, with the expected chars replaced in the file names.

@oguzeldereli1
Copy link
Contributor

@danmoseley will do, thank you!

@oguzeldereli1
Copy link
Contributor

oguzeldereli1 commented Mar 27, 2022

@danmoseley I have verified with SharpLibZip FastZip that the zip file results in all characters replaced with underscores. Creating a pull request now.

@danmoseley
Copy link
Member

I wouldn't bother with \0 if it isn't obvious how someone would make such things.

Also of course that would be invalid even on Unix, so it's unlikely any mainstream tool would allow you to name streams that way, as they could never be written to a file under that name.

danmoseley added a commit to dotnet/runtime-assets that referenced this issue Mar 27, 2022
)

* Added Test Zip File (dotnet/runtime#67201)

* Use descriptive name

* Added Zip File containing files with characters invalid in Windows

Co-authored-by: Dan Moseley <[email protected]>
@oguzeldereli1
Copy link
Contributor

@danmoseley How should I proceed now? Your original post suggests that I should wait for a PR and add tests. How would I go about adding tests and running them?

(I won't be able to attend to this for a few hours since I will probably have to sleep (it's late here))

@danmoseley
Copy link
Member

How would I go about adding tests and running them?

First you need to get this repo cloned, built, and existing tests passing. Start at https://github.com/dotnet/runtime/blob/main/docs/workflow/README.md -- follow instructions for libraries.

@smoothdeveloper
Copy link
Author

@danny427 at first measure you may:

  • pull the same .zip file, to iron your testing a bit (which will be a non reg one, once adjustment is done)
  • try to write a small archive with "non cross platform file names" in it with the underlying Zip infrastructure in the BCL (not sure it is doable as I never tried)

@danmoseley
Copy link
Member

@Danyy427 once he has tests passing locally (with no changes) should follow these instructions https://github.com/dotnet/runtime-assets/blob/main/README.md#optional-step-local-testing in order to be able to add a new test that consumes his new zip file.

@danmoseley danmoseley removed the help wanted [up-for-grabs] Good issue for external contributors label Mar 28, 2022
@oguzeldereli1
Copy link
Contributor

oguzeldereli1 commented Mar 28, 2022

@danmoseley I have been attempting to build the repo with the instructions but the build fails with a couple of errors such as this one:

error SYSLIB0003: 'PermissionSet' is obsolete: 'Code Access Security is not supported or honored by the runtime.' [D:\Runtime\runtime\src\tasks\MonoTargetsTasks\ILStrip\AssemblyStripper\AssemblyStripper.csproj]

I run the build command like this:

./build.cmd clr+libs -rc Release

and I have all of the required components that are listed. I came across this page but I don't know how to fix it in the build per se.

@oguzeldereli1
Copy link
Contributor

oguzeldereli1 commented Mar 29, 2022

@danmoseley I have just finished the sanitization to GetFileName_Windows but I forgot to do it for directories. Is there a method like GetFileName_Windows for directories that you know of? I have been searching for it but I am not familiar with the project structure.

@danmoseley
Copy link
Member

@danmoseley Do I add both the tests and sanitization in one go or do I first add the tests, open a pull request, see that it fails and then add the sanitization to make them pass?

It is always best to write the test(s) and verify it fails before attempting to fix anything. Primarily because that confirms you have written a useful test.

I have just finished the sanitization to GetFileName_Windows

I didn't look at the code very hard 😄 It seems the purpose of that method is to find the "file part" of the entry. It's then exposed eg in ZipArchiveEntry.Name. We probably shouldn't "lie" there.

My suggestion is to add the sanitization at the point the file has to be written. It looks like here, FullName is the whole relative path.

string fileDestinationPath = Path.GetFullPath(Path.Combine(destinationDirectoryFullPath, source.FullName));

One way to do this might be to add something like an "internal string SantizedFullName { get { .. }}" property (or maybe FileSystemSafeFullName?)to both ZipArchiveEntry.Windows.cs and ZipArchiveEntry.Unix.cs. On Unix it just returns FullName. On Windows it sanitizes it. Then on the line above, use SanitizedFullName instead of FullName.

@oguzeldereli1
Copy link
Contributor

@danmoseley I have created a pull requests for the test. #67332

@oguzeldereli1
Copy link
Contributor

@danmoseley checks are done, some tests failed as expected

@oguzeldereli1
Copy link
Contributor

oguzeldereli1 commented Mar 30, 2022

@danmoseley In your last post, you said

One way to do this might be to add something like an "internal string SantizedFullName { get { .. }}" property (or maybe FileSystemSafeFullName?)to both ZipArchiveEntry.Windows.cs and ZipArchiveEntry.Unix.cs. On Unix it just returns FullName. On Windows it sanitizes it. Then on the line above, use SanitizedFullName instead of FullName.

I do not understand why ValidFullName shouldn't be public. Aren't we trying to reach it outside of its assembly? One is from System.IO.Compression.Zipfile the other System.IO.Compression, am I misinterpreting how internal works.

@oguzeldereli1
Copy link
Contributor

@danmoseley Also should I build the System.IO.Compression again before using ValidFullName from ZipFileExtensions.ZipArchiveEntry.Extract.cs?

When ValidFullName is internal and I build the project, I still cannot use it from ZipArchiveEntry.cs, I am getting a CS1061

On the other hand if I declare ValidFullName as public the library won't build at all,

C:\Users\Asus\.nuget\packages\microsoft.dotnet.apicompat\7.0.0-beta.22171.2\build\Microsoft.DotNet.ApiCompat.targets(94,5): error : Compat issues with assembly System.IO.Compression: [D:\Runtime\runtime\src\libraries\System.IO.Compression\src\System.IO.Compression.csproj]
C:\Users\Asus\.nuget\packages\microsoft.dotnet.apicompat\7.0.0-beta.22171.2\build\Microsoft.DotNet.ApiCompat.targets(94,5): error : MembersMustExist : Member 'public System.String System.IO.Compression.ZipArchiveEntry.ValidFullName.get()' does not exist in the reference but it does exist in the implementation. [D:\Runtime\runtime\src\libraries\System.IO.Compression\src\System.IO.Compression.csproj]
C:\Users\Asus\.nuget\packages\microsoft.dotnet.apicompat\7.0.0-beta.22171.2\build\Microsoft.DotNet.ApiCompat.targets(94,5): error : Compat issues with assembly System.IO.Compression: [D:\Runtime\runtime\src\libraries\System.IO.Compression\src\System.IO.Compression.csproj]
C:\Users\Asus\.nuget\packages\microsoft.dotnet.apicompat\7.0.0-beta.22171.2\build\Microsoft.DotNet.ApiCompat.targets(94,5): error : MembersMustExist : Member 'public System.String System.IO.Compression.ZipArchiveEntry.ValidFullName.get()' does not exist in the reference but it does exist in the implementation. [D:\Runtime\runtime\src\libraries\System.IO.Compression\src\System.IO.Compression.csproj]
C:\Users\Asus\.nuget\packages\microsoft.dotnet.apicompat\7.0.0-beta.22171.2\build\Microsoft.DotNet.ApiCompat.targets(94,5): error : Compat issues with assembly System.IO.Compression: [D:\Runtime\runtime\src\libraries\System.IO.Compression\src\System.IO.Compression.csproj]
C:\Users\Asus\.nuget\packages\microsoft.dotnet.apicompat\7.0.0-beta.22171.2\build\Microsoft.DotNet.ApiCompat.targets(94,5): error : MembersMustExist : Member 'public System.String System.IO.Compression.ZipArchiveEntry.ValidFullName.get()' does not exist in the reference but it does exist in the implementation. [D:\Runtime\runtime\src\libraries\System.IO.Compression\src\System.IO.Compression.csproj]

@danmoseley
Copy link
Member

danmoseley commented Mar 30, 2022

Ah. It looks like you can't piggy back in ZipArchiveEntry.Windows.cs (which is in System.IO.Compression) because you need it in ZipFileExtensions.ZipArchiveEntry.Extract.cs (which is in System.IO.Compression.ZipFile)

Instead I suggest creating something like ZipFileExtensions.ZipArchiveEntry.Extract.Windows.cs and putting it next to ZipFileExtensions.ZipArchiveEntry.Extract.cs and editing System.IO.Compression.ZipFile.csproj so it's only used on Windows. Hmm, but that csproj does not have a Windows-specific build. It would need $(NetCoreAppCurrent)-windows added to <TargetFrameworks> so you can use Condition="'$(TargetPlatformIdentifier)' == 'windows'" to include this new file.

I'm not familiar with all these arrangements and why bits of zip are in S.IO.C and bits are in S.IO.C.Z.. @carlossanlop do you have a suggestion?

@oguzeldereli1
Copy link
Contributor

oguzeldereli1 commented Mar 30, 2022

@danmoseley Instead of adding ValidFileName to ZipArchiveEntry.Windows.cs and ZipArchiveEntry.Unix.cs separately, could I add it to ZipArchiveEntry.cs directly and check for the platform inside of get. If it is windows I sanitize the characters, if not I sanitize \0 or just return FileName as is?

@danmoseley
Copy link
Member

Ideally we don't check OS at runtime.

@ericstj what is our base for adding a windows target to this library?

@oguzeldereli1
Copy link
Contributor

@danmoseley I don't know if it would work (I cannot test it right now) but we could maybe add _ValidFullName to ZipArchiveEntry.Windows.cs and ZipArchiveEntry.Unix.cs, declare them as internal, then declare a public property ValidFullName which just returns _ValidFullNamein ZipArchiveEntry.cs

@carlossanlop
Copy link
Contributor

Ah. It looks like you can't piggy back in ZipArchiveEntry.Windows.cs (which is in System.IO.Compression) because you need it in ZipFileExtensions.ZipArchiveEntry.Extract.cs (which is in System.IO.Compression.ZipFile)

If I'm understanding this correctly, you're trying to consume code from System.IO.Compression.ZipFile in System.IO.Compression. Correct? One option is to put the shared code in a new file in src/libraries/Common/System/IO/Compression, and then include that file in both S.IO.Compression and S.IO.Compression.ZipFile csproj projects. As long as the code is internal, it should work for both.

A great example of this practice are the src/libraries/Common/src/System/IO/PathInternal*.cs files, which are consumed in a few different assemblies.

@oguzeldereli1
Copy link
Contributor

@carlossanlop We are also trying to make some of the code work specifically on Windows and some of it on Unix, like ZipArchiveEntry.Windows.cs and ZipArchiveEntry.Unix.cs which should also be a common code in Compression and Compression.Zipfile

@ericstj
Copy link
Member

ericstj commented Mar 31, 2022

@ericstj what is our base for adding a windows target to this library?

Add $(NetCoreAppCurrent)-windows to this

<TargetFrameworks>$(NetCoreAppCurrent)-Unix;$(NetCoreAppCurrent)-Browser;$(NetCoreAppCurrent)</TargetFrameworks>

and make sure you condition your new files on TargetPlatformIdentifier like this:

<ItemGroup Condition="'$(TargetPlatformIdentifier)' == 'windows'">
<Compile Include="System\IO\Compression\ZipArchiveEntry.Windows.cs" />
<Compile Include="$(CommonPath)Interop\Windows\Interop.Libraries.cs"
Link="Common\Interop\Windows\Interop.Libraries.cs" />

@oguzeldereli1
Copy link
Contributor

@danmoseley I do not know how I should be using this knowledge. I tried to do something but it's just errors everywhere now :)

I added two files ZipFileValidName_Windows.cs and ZipFileValidName_Unix.cs to src/libraries/Common/System/IO/Compression, added both of the files to their relative target platforms in the csproj files. Like this:

System.IO.Compression.sln:

<!-- Windows specific files -->
...
<Compile Include="$(CommonPath)System\IO\Compression\ZipFileValidName_Windows.cs"
             Link="Common\System\IO\Compression\ZipFileValidName_Windows.cs" />

<!-- Unix specific files -->
...
<Compile Include="$(CommonPath)System\IO\Compression\ZipFileValidName_Unix.cs"
             Link="Common\System\IO\Compression\ZipFileValidName_Unix.cs" />

and to System.IO.Compression.ZipFile I first added $(NetCoreAppCurrent)-windows; to TargetFrameworks then added the files:

  <ItemGroup Condition="'$(TargetPlatformIdentifier)' == 'windows'">
    <Compile Include="System\IO\Compression\ZipArchiveEntry.Windows.cs" />
    <Compile Include="$(CommonPath)Interop\Windows\Interop.Libraries.cs"
             Link="Common\Interop\Windows\Interop.Libraries.cs" />
    <Compile Include="$(CommonPath)System\IO\Compression\ZipFileValidName_Windows.cs"
             Link="Common\System\IO\Compression\ZipFileValidName_Windows.cs" />
  </ItemGroup>

<!-- Unix specific files -->
...
<Compile Include="$(CommonPath)System\IO\Compression\ZipFileValidName_Unix.cs"
             Link="Common\System\IO\Compression\ZipFileValidName_Unix.cs" />

Finally changed the FullName to ValidFullName in ZipExtensions.ZipArchiveEntry.Extract.cs but now every ZipArchiveEntry in the file is giving a CS0436 error.

@danmoseley
Copy link
Member

@Danyy427 can you push your changes to your branch, and one of us can take a look?

@oguzeldereli1
Copy link
Contributor

@danmoseley I pushed my changes, note that some weird character was written at the start of the csproj files, probably something wrong with vs or notepad++, the last commit was to remove those

@oguzeldereli1
Copy link
Contributor

@danmoseley I have also added sanitization.

@oguzeldereli1
Copy link
Contributor

@danmoseley did you have a chance to look at the changes?

@oguzeldereli1
Copy link
Contributor

@danmoseley Actually instead of trying to add a ValidFullName to S.IO.C and trying to use it from S.IO.C.Z, why don’t we just write platform dependent methods to S.IO.C.Z and avoid the shared code part altogether. Is there a particular reason why we are trying to avoid writing methods to sanitize the filename?

@danmoseley
Copy link
Member

@carlossanlop do you have a preference?

@oguzeldereli1
Copy link
Contributor

oguzeldereli1 commented Apr 2, 2022

@danmoseley I was going to try out writing sanitization as a method and I did do it for windows and Unix but there seem to be 4 target platforms. It seems that Unix and Browser go together but what about net7.0 without any target platform specified. Is that supposed to have sanitization or not?

@oguzeldereli1
Copy link
Contributor

@danmoseley I made the test that I have written pass locally using a method to sanitize the filename. Every other test fails miserably tho

@oguzeldereli1
Copy link
Contributor

@danmoseley I have pushed the changes that made the local test pass, how should I deal with tests that expect the extraction to fail when there are invalid characters in the filename?

@danmoseley
Copy link
Member

how should I deal with tests that expect the extraction to fail when there are invalid characters in the filename?

You'd update those tests so they expect the new behavior.

@oguzeldereli1
Copy link
Contributor

oguzeldereli1 commented Apr 4, 2022

@danmoseley there are some tests that are made specifically to check for errors when they encounter invalid chars. Should I delete those tests as they are no longer needed or should I make sure all of the zips in their test cases are extracted correctly with Assert.True's.
Like for example Windows_ZipWithInvalidFileNames_ThrowsException in Zipfile.Create tests

@oguzeldereli1
Copy link
Contributor

@danmoseley I fixed all of the tests and they all passed on my local system. Instead of deleting the ThrowsException tests, I merged the entirety of them into my own test function that I have written initially so we can test all of the invalid and null zip file test cases. I have pushed the code to #67332 and if they pass here as well they should be good to go.

@danmoseley
Copy link
Member

fixed by #67332

@ghost ghost locked as resolved and limited conversation to collaborators May 13, 2022
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
area-System.IO.Compression good first issue Issue should be easy to implement, good for first-time contributors
Projects
None yet
Development

No branches or pull requests

7 participants