导入报错:Limits: MIN_INFLATE_RATIO: 0.010000, Entry: xl/drawings/drawing1.xml

news2024/11/22 20:54:35

今天突然遇到一个现场提出的问题:说导入文件导入不成功,咋突然有这个问题

2023-05-23 14:19:11,174 ERROR [http-nio-9104-exec-5] o.a.c.c.C.[.[.[.[dispatcherServlet] [DirectJDKLog.java : 175] Servlet.service() for servlet [dispatcherServlet] in context with path [] threw exception [Request processing failed; nested exception is org.apache.poi.ooxml.POIXMLException: Zip bomb detected! The file would exceed the max. ratio of compressed file size to the size of the expanded data.
This may indicate that the file is used to inflate memory usage and thus could pose a security risk.
You can adjust this limit via ZipSecureFile.setMinInflateRatio() if you need to work with files which exceed this limit.
Uncompressed size: 2048444, Raw/compressed size: 20480, ratio: 0.009998
Limits: MIN_INFLATE_RATIO: 0.010000, Entry: xl/drawings/drawing1.xml] with root cause
java.io.IOException: Zip bomb detected! The file would exceed the max. ratio of compressed file size to the size of the expanded data.
This may indicate that the file is used to inflate memory usage and thus could pose a security risk.
You can adjust this limit via ZipSecureFile.setMinInflateRatio() if you need to work with files which exceed this limit.
Uncompressed size: 2048444, Raw/compressed size: 20480, ratio: 0.009998
Limits: MIN_INFLATE_RATIO: 0.010000, Entry: xl/drawings/drawing1.xml

定位代码,源头是new XSSFWorkbook(文件)  爆出的错

上面的翻译过来大概是这样:

在提示我们调整比例。

下面我们来模拟和解决
代码: 

    public static void main(String[] args) throws Exception {
        //ZipSecureFile.setMinInflateRatio(0.001);
        File file = new File("C:/Users/Lenovo/Desktop/a/1.xlsx");
        InputStream inputStream = new FileInputStream(file);
        XSSFWorkbook workbook = new XSSFWorkbook(inputStream);
        FileOutputStream outputStream = new FileOutputStream(new File("C:/Users/Lenovo/Desktop/a/76543.xlsx"));
        workbook.write(outputStream);
        workbook.close();
        outputStream.close();
    }

 这里的文件 记住

 只有sheet1有使用,是导入的文件内容,Sheet2,Sheet3是空白,也没有使用,下载模板不知道为什么要下载下来。再说sheet1不一样写一个标识名称吗? 哎,新手上路,主要安全啊。规范点,专业点。

 

你看看,这不是报错了,而且导入sheet1中只有50条记录,也不是很多XSSFWorkbook话说支持百万,只要内存支持,咋可能40几条就干倒了。

看提示什么压缩爆炸,第一次遇到,然后就排查,源头是里面有一个压缩爆炸的判断

package org.apache.poi.openxml4j.util;

import static org.apache.poi.openxml4j.util.ZipSecureFile.MAX_ENTRY_SIZE;
import static org.apache.poi.openxml4j.util.ZipSecureFile.MIN_INFLATE_RATIO;

import java.io.EOFException;
import java.io.FilterInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.Locale;
import java.util.zip.ZipException;

import org.apache.commons.compress.archivers.zip.ZipArchiveEntry;
import org.apache.commons.compress.archivers.zip.ZipArchiveInputStream;
import org.apache.commons.compress.utils.InputStreamStatistics;
import org.apache.poi.openxml4j.exceptions.NotOfficeXmlFileException;
import org.apache.poi.util.IOUtils;
import org.apache.poi.util.Internal;

@Internal
public class ZipArchiveThresholdInputStream extends FilterInputStream {
    // don't alert for expanded sizes smaller than 100k
    private static final long GRACE_ENTRY_SIZE = 100*1024L;

    private static final String MAX_ENTRY_SIZE_MSG =
        "Zip bomb detected! The file would exceed the max size of the expanded data in the zip-file.\n" +
        "This may indicates that the file is used to inflate memory usage and thus could pose a security risk.\n" +
        "You can adjust this limit via ZipSecureFile.setMaxEntrySize() if you need to work with files which are very large.\n" +
        "Uncompressed size: %d, Raw/compressed size: %d\n" +
        "Limits: MAX_ENTRY_SIZE: %d, Entry: %s";

    private static final String MIN_INFLATE_RATIO_MSG =
        "Zip bomb detected! The file would exceed the max. ratio of compressed file size to the size of the expanded data.\n" +
        "This may indicate that the file is used to inflate memory usage and thus could pose a security risk.\n" +
        "You can adjust this limit via ZipSecureFile.setMinInflateRatio() if you need to work with files which exceed this limit.\n" +
        "Uncompressed size: %d, Raw/compressed size: %d, ratio: %f\n" +
        "Limits: MIN_INFLATE_RATIO: %f, Entry: %s";

    /**
     * the reference to the current entry is only used for a more detailed log message in case of an error
     */
    private ZipArchiveEntry entry;
    private boolean guardState = true;

    public ZipArchiveThresholdInputStream(InputStream is) {
        super(is);
        if (!(is instanceof InputStreamStatistics)) {
            throw new IllegalArgumentException("InputStream of class "+is.getClass()+" is not implementing InputStreamStatistics.");
        }
    }

    @Override
    public int read() throws IOException {
        int b = super.read();
        if (b > -1) {
            checkThreshold();
        }
        return b;
    }

    @Override
    public int read(byte[] b, int off, int len) throws IOException {
        int cnt = super.read(b, off, len);
        if (cnt > -1) {
            checkThreshold();
        }
        return cnt;
    }

    @Override
    public long skip(long n) throws IOException {
        long cnt = IOUtils.skipFully(super.in, n);
        if (cnt > 0) {
            checkThreshold();
        }
       return cnt;
    }

    /**
     * De-/activate threshold check.
     * A disabled guard might make sense, when POI is processing its own temporary data (see #59743)
     *
     * @param guardState {@code true} (= default) enables the threshold check
     */
    public void setGuardState(boolean guardState) {
        this.guardState = guardState;
    }

    private void checkThreshold() throws IOException {
        if (!guardState) {
            return;
        }

        final InputStreamStatistics stats = (InputStreamStatistics)in;
        final long payloadSize = stats.getUncompressedCount();

        long rawSize;
        try {
            rawSize = stats.getCompressedCount();
        } catch (NullPointerException e) {
            // this can happen with a very specially crafted file
            // see https://issues.apache.org/jira/browse/COMPRESS-598 for a related bug-report
            // therefore we try to handle this gracefully for now
            // this try/catch can be removed when COMPRESS-598 is fixed
            rawSize = 0;
        }

        final String entryName = entry == null ? "not set" : entry.getName();

        // check the file size first, in case we are working on uncompressed streams
        if(payloadSize > MAX_ENTRY_SIZE) {
            throw new IOException(String.format(Locale.ROOT, MAX_ENTRY_SIZE_MSG, payloadSize, rawSize, MAX_ENTRY_SIZE, entryName));
        }

        // don't alert for small expanded size
        if (payloadSize <= GRACE_ENTRY_SIZE) {
            return;
        }

        double ratio = rawSize / (double)payloadSize;
        if (ratio >= MIN_INFLATE_RATIO) {
            return;
        }

        // one of the limits was reached, report it
        throw new IOException(String.format(Locale.ROOT, MIN_INFLATE_RATIO_MSG, payloadSize, rawSize, ratio, MIN_INFLATE_RATIO, entryName));
    }

    ZipArchiveEntry getNextEntry() throws IOException {
        if (!(in instanceof ZipArchiveInputStream)) {
            throw new IllegalStateException("getNextEntry() is only allowed for stream based zip processing.");
        }

        try {
            entry = ((ZipArchiveInputStream) in).getNextZipEntry();
            return entry;
        } catch (ZipException ze) {
            if (ze.getMessage().startsWith("Unexpected record signature")) {
                throw new NotOfficeXmlFileException(
                        "No valid entries or contents found, this is not a valid OOXML (Office Open XML) file", ze);
            }
            throw ze;
        } catch (EOFException e) {
            return null;
        }
    }

    /**
     * Sets the zip entry for a detailed logging
     * @param entry the entry
     */
    void setEntry(ZipArchiveEntry entry) {
        this.entry = entry;
    }
}

文件也不大啊,40几条,咋就爆炸了,看提示调整参数值,也就是触发爆炸比例,让不报错

ZipSecureFile.setMinInflateRatio(0.001);

主要要加载报错代码执行

如下:

    public static void main(String[] args) throws Exception {
        ZipSecureFile.setMinInflateRatio(0.001);
        File file = new File("C:/Users/Lenovo/Desktop/a/1.xlsx");
        InputStream inputStream = new FileInputStream(file);
        XSSFWorkbook workbook = new XSSFWorkbook(inputStream);
        FileOutputStream outputStream = new FileOutputStream(new File("C:/Users/Lenovo/Desktop/a/76543.xlsx"));
        workbook.write(outputStream);
        workbook.close();
        outputStream.close();
    }

运行后正常,确实没有报爆炸的错误,对应文件也可以查看

 准备和对应开发人,说先试一下

与此同时,我觉得,以前并没有遇到这样的问题啊,这文件也不大,在看看文件里面的Sheet2,Sheet3都是空白的,也会进入压缩,抱着试一试的心态,就去掉多余模板的sheet2,sheet3,也不是道复制哪边的,太不认真了,再次执行原来的代码

    public static void main(String[] args) throws Exception {
        File file = new File("C:/Users/Lenovo/Desktop/a/2.xlsx");
        InputStream inputStream = new FileInputStream(file);
        XSSFWorkbook workbook = new XSSFWorkbook(inputStream);
        FileOutputStream outputStream = new FileOutputStream(new File("C:/Users/Lenovo/Desktop/a/76543.xlsx"));
        workbook.write(outputStream);
        workbook.close();
        outputStream.close();
    }

运行竟然没有报错,注意2.xlsx中只有Sheet1,要导入的内容。

我然后再50条基础上,增加了10倍,500,再次运行,还是正常的。

所有最终的方案,是去掉多余的sheet2,sheet3,调整导入模板,减少压缩占比。

但是后来,又新增Sheet2,sheet3,再次调用代码,发现又可以使用

这时候只能定位是模板中Sheet2,sheet3格式有问题,最终的解决方案也是调整模板,但是了解了一个压缩爆炸的思想,还是挺有意思的。

总结:

1. 查看模板是不是有问题

2.调整触发压缩爆炸的参数ZipSecureFile.setMinInflateRatio(0.001);

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/559351.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

VMwareESXI虚拟机黑群晖7.2 正式版 (懒人包)

版本说明&#xff1a; VMware Workstation 桌面版虚拟机&#xff0c;可下载VMware专用版本 VMware ESXi虚拟机&#xff0c;可以下载OVA版本 VMware Workstation桌面版虚拟机 使用教程&#xff1a; 1.下载VMware专用版本&#xff0c;然后进行解压&#xff0c;双击解压出来的&q…

前端Vue:权限管理,给角色分配权限

&#x1f449;前端-Vue权限控制&#xff0c;菜单权限&#xff0c;按钮权限_一人创客的博客-CSDN博客 目录 介绍&#xff1a; 前端权限的概念&#xff1a; 前端权限的意义&#xff1a; Vue权限管理的代码实现&#xff1a; 菜单 刷新界⾯菜单消失 标识⽤户名, ⽅便查看当前…

chatgpt赋能Python-python_kali

Python与Kali Linux&#xff1a;SEO攻击的更有效方法 介绍 Python是一种强大且高度灵活的编程语言&#xff0c;也是许多安全专家、黑客和网络攻击者所喜欢的工具之一。Kali Linux是一个专注于安全审计、渗透测试和网络安全的Linux发行版&#xff0c;其中包含了许多流行的安全…

微服务开发系列 第四篇:分页查询

总概 A、技术栈 开发语言&#xff1a;Java 1.8数据库&#xff1a;MySQL、Redis、MongoDB、Elasticsearch微服务框架&#xff1a;Spring Cloud Alibaba微服务网关&#xff1a;Spring Cloud Gateway服务注册和配置中心&#xff1a;Nacos分布式事务&#xff1a;Seata链路追踪框架…

Chat GPT 教您如何发现和处理无效数据

Chat GPT 教您如何发现和处理无效数据 在进行数据管理时&#xff0c;无论是数据分析、数据挖掘还是机器学习项目&#xff0c;无效数据都可能对结果造成严重的影响。因此&#xff0c;发现和处理无效数据变得至关重要。本文将从如何处理无效数据的角度&#xff0c;详细探讨数据清…

数据结构与算法(五)

哈希表&#xff08;hash&#xff09; 什么是hash&#xff1f; 散列,是把任意长度的输入通过散列算法变换成固定长度输出&#xff0c;该输出的值就是散列值。这种转换是一种压缩映射。映射表达的是一一对应的关系&#xff0c;也就是说&#xff0c;散列值的空间通常会小于输入空…

[算法前沿]--014-DeepSpeed-Chat 模型训练实战<下>

文章目录 1.实战Step1:监督微调1.1 任务说明: 使用标定的数据对预训练模型进行微调评价与测试:2 实战Step2:Reward模型微调3.实战Step3:RLHF训练3.评价与测试4.QA参考1.实战Step1:监督微调 基础语言模型是指只在大规模文本语料中进行了预训练的模型,未经过指令和下游任务…

淘宝商品历史价格API接口 调用说明及功能介绍

淘宝商品历史价格API是一款可以帮助用户获取淘宝商品历史价格数据的接口。通过该接口&#xff0c;用户可以轻松地获取某个商品在过去一段时间中的价格趋势和波动情况&#xff0c;以便更好地了解该商品的市场走势和价值变化情况。 该API具备以下功能&#xff1a; 1. 支持多种查…

对于大流量请求的处理方案(NATNginx)

情况描述&#xff1a; 如图所示&#xff0c;厂家的A服务器&#xff0c;到客户的C服务器不通&#xff0c;需要我这边通过B服务器做一次流量转发。 由于&#xff0c;每次请求数据流都太大&#xff0c;怕HTTPS方式&#xff0c;会出现请求超时&#xff0c;断开连接。 解决方案&am…

什么是自动化测试框架?我们该如何搭建自动化测试框架?

无论是在自动化测试实践&#xff0c;还是日常交流中&#xff0c;经常听到一个词&#xff1a;框架。之前学习自动化测试的过程中&#xff0c;一直对“框架”这个词知其然不知其所以然。 最近看了很多自动化相关的资料&#xff0c;加上自己的一些实践&#xff0c;算是对“框架”…

Codeium:一个免费的、支持70多种编程语言的、可以与你对话的智能编程助手,让你从繁琐的代码中解放出来

摘要 Codeium&#xff1a;免费的人工智能代码加速工具&#xff0c;让编程变得更简单、更快、更有趣 如何使用Codeium来提高编程效率和质量&#xff1f;一篇文章教你掌握Codeium的三大功能&#xff1a;代码完成、聊天和搜索 Codeium vs GitHub Copilot&#xff1a;哪个更适合你…

Linux的软件生态与两个方面,客户端/Linux软件下载安装的认识,yum源/仓库(repo)与yum指令的本质,yum指令操作等

铺垫1&#xff1a;服务器属于硬件 服务器是一种计算机硬件设备&#xff0c;主要用于存储、管理和处理数据以及为其他计算机提供服务。服务器通常具有高性能的处理器、大容量的硬盘、大内存和高速网络连接等特点&#xff0c;可以提供各种服务&#xff0c;如网站托管、电子邮件服…

【教程】对视频平台授权时,加密机设备如何固定IP?

我们在此前的文章中也介绍过&#xff0c;我们的视频平台都是通过加密机、加密狗、激活码三种方式进行服务授权的&#xff0c;其中&#xff0c;加密机使用得较多。具体注意事项可以查看这篇文章&#xff1a;加密机授权注意事项汇总及解决方法。 加密机在使用时&#xff0c;需要在…

bat操作git(一键提交)

添加环境变量&#xff1a;D:\Git\Git\cmd 环境变量添加完毕后就可以直接在命令框使用git命令了 脚本实现 实现一键完成远程仓库的更新 echo off git add . git commit -m "daily push data-structure-and-algorithms" git push echo push respostory successful…

python包之matplotlib基础概念和代码详解

1 基础概念 Figure&#xff1a; 可以理解为 canvas(画布)&#xff0c;在画布上可以展示一个或多个Axes Axes&#xff1a;中文翻译为轴&#xff0c;但与数学中的概念不同&#xff0c;Axes可以理解为子画布&#xff0c;它属于Figure。也可以理解为它就是一个图形或绘制图形的区…

为什么有了IP地址,还需要MAC地址呢?

不知道大家有没有困惑&#xff1a;为什么有了IP地址&#xff0c;还需要MAC地址呢&#xff1f;他们之间到底有什么联系&#xff1f;又有什么区别&#xff1f;是不是有一个是多余的&#xff1f; 流言传到了“IP地址”和“MAC地址”的耳朵里&#xff0c;他俩也非常苦恼&#xff0c…

【Unity】 UI自适应案例

UI自适应案例 案例一:背包自动布局1. 创建背包面板2. 背包子项自动布局3. C#代码:动态添加子项到背包中案例二:文字自适应高度1. 创建文字面板2. 组件基本设置3. C#代码:动态更新文字并自适应高度案例一:背包自动布局 需求:动态添加背包组件,设定每行特定个数并自动匹配…

抖音seo矩阵系统源码开发(三)

抖音seo框架分析&#xff1a; 抖音SEO源码主要有两种框架&#xff1a; 一是基于爬虫的框架&#xff0c;通过爬取抖音平台的内容&#xff0c;提取关键词和标签等信息&#xff0c;再结合优化技巧&#xff0c;最终实现SEO效果的提升&#xff1b;二是基于粉丝互动和品牌策划的框架…

制作iOS越狱deb插件+dpkg命令行教程

iOS越狱deb插件的制作 dpkg命令行教程 deb安装包的制作 介绍 Cydia Sileo都是基于Debian开发的, 所以插件都是打包成.deb格式 deb包是Debian软件包格式&#xff0c;文件扩展名为.deb。是Debian系统(包含Debian和Ubuntu等)专属安装包格式。 deb包在Linux操作系统中类似于wi…

探索小程序容器在软件应用架构中的角色和优势

今年来&#xff0c;随着软件及开源技术的发展&#xff0c;软件应用架构的概念也随之流行起来。它提供了一种组织和设计软件系统的有效方法&#xff0c;具有许多优势和好处&#xff1a; 模块化和可维护性&#xff1a;软件应用架构将系统拆分为模块化的组件&#xff0c;每个组件负…