A Bug encountered when C#decompressing zip files at the end of 2022

A Bug encountered when C#decompressing zip files at the end of 2022

Recently, when checking an upload function, the client uploads a zip file. After going to the server, I use the C#code to decompress the zip file to decompress the uploaded file and verify whether it is a file type that is allowed to upload. I also need to verify that the file suffix is changed indiscriminately. I have to go through everything on the header of the file. As a result, there is a monster when decompressing the zip file.

最后更新 12/23/2022 9:39 AM
江湖人士
预计阅读 4 分钟
分类
.NET
标签
.NET C#

This article was submitted by netizens.

Author: Jianghu person

Original title: A bug encountered when C#decompressing zip files at the end of 2022

Original link: jhrs.com/2022/46060.html

Recently, when checking an upload function, the client uploads a zip file. After going to the server, I use the C#code to decompress the zip file to decompress the uploaded file and verify whether it is a file type that is allowed to upload. I also need to verify that the file suffix is changed indiscriminately. I have to go through everything on the header of the file. As a result, there is a monster when decompressing the zip file.

C#Extract zip file

先说一下前文(或者上下文),在 IIS 上部署了一个文件服务站点,用于上传各类文件,流程上是先上传到站点根目录里面随机创建的一个临时目录(这里采用偷懒方案,直接使用 guid 作为目录名创建),先通过文件验证后再将其通过代码剪切或者复制到正式存档目录,C# 复制或者移动文件的代码可以参考江湖人士网的这篇文章。昨天快下班时发现上传 zip 文件时报错,在文件服务根站点创建了很多很多的 guid 开头的目录,我的妹呀,这下玩犊子了,事出反常必有妖啊,肯定代码出错了。

Bug decompression code

It's almost the end of 2022. After this bug occurred, I quickly set up a simulation environment to run around and found that the following original code did have problems. The original code is as follows:

/// <summary>
/// 解压文件
/// </summary>
/// <param name="saveDir">保存目录</param>
/// <param name="stream"></param>
public static void UnZipFiles(string saveDir, Stream stream)
{
    using (ZipInputStream s = new ZipInputStream(stream))
    {
        ZipEntry theEntry;
        while ((theEntry = s.GetNextEntry()) != null)
        {
            string directoryName = $"{saveDir}{Path.GetDirectoryName(theEntry.Name)}\\";
            string fileName = Path.GetFileName(theEntry.Name);
            Directory.CreateDirectory(directoryName);
            using (FileStream streamWriter = File.Create(directoryName + fileName))
            {
                byte[] data = new byte[2048];
                while (true)
                {
                    int size = s.Read(data, 0, data.Length);
                    if (size > 0)
                    {
                        streamWriter.Write(data, 0, size);
                    }
                    else
                    {
                        break;
                    }
                }
            }
        }
    }
}

对了,这里需要说明一下,这是以前的老项目,因此压缩,解压使用了 ICSharpCode.SharpZipLib.Zip 这个组件。

When I opened the source code and took a look, I found the problem at a glance. The logic was not strict, and the decompression file was saved and the directory was directly spliced.

How to fix this bug?

知道了问题所在,修复自然简单,调用Path.Combine方法即可,解压时再判断一下是目录还是文件即可,最终修复后的代码如下:

/// <summary>
/// 解压文件
/// </summary>
/// <param name="saveDir">保存目录</param>
/// <param name="stream"></param>
public static void UnZipFiles(string saveDir, Stream stream)
{
    using (ZipInputStream s = new ZipInputStream(stream))
    {
        ZipEntry theEntry;
        string directoryName, file, fileName;
        while ((theEntry = s.GetNextEntry()) != null)
        {
            directoryName = Path.Combine(saveDir, Path.GetDirectoryName(theEntry.Name));
            fileName = Path.GetFileName(theEntry.Name);
            Directory.CreateDirectory(directoryName);
            file = Path.Combine(directoryName, fileName);

            if (theEntry.IsFile)
            {
                using (FileStream streamWriter = File.Create(file))
                {
                    byte[] data = new byte[2048];
                    while (true)
                    {
                        int size = s.Read(data, 0, data.Length);
                        if (size > 0)
                        {
                            streamWriter.Write(data, 0, size);
                        }
                        else
                        {
                            break;
                        }
                    }
                }
            }
        }
    }
}
Keep Exploring

延伸阅读

更多文章
同分类 / 同标签 4/22/2026

Support for. NET by operating system versions (250707 update)

Use virtual machines and test machines to test the support of each version of the operating system for. NET. After installing the operating system, it is passed by measuring the corresponding running time of the installation and being able to run the Stardust Agent.

继续阅读
同分类 / 同标签 2/7/2026

Summary of experience in using AOT

From the very beginning of project creation, you should develop a good habit of conducting AOT release testing in a timely manner whenever new features are added or newer syntax is used.

继续阅读