POI 解析Excel Cannot remove block[ xx ]; out of range[ 0 - xx ] 问题分析

问题起因

一哥们在做Excel文件解析,大概流程是 从指定FTP -> 下载Excel(2003)文件 -> 解析文件数据

在本地测试解析文件没问题,发布到测试环境就出问题,具体异常如下:

java.io.IOException: Cannot remove block[ 922746880 ]; out of range[ 0 - 43921 ]
	at org.apache.poi.poifs.storage.BlockListImpl.remove(BlockListImpl.java:98)
	at org.apache.poi.poifs.storage.RawDataBlockList.remove(RawDataBlockList.java:34)
	at org.apache.poi.poifs.storage.BlockAllocationTableReader.<init>(BlockAllocationTableReader.java:139)
	at org.apache.poi.poifs.filesystem.POIFSFileSystem.<init>(POIFSFileSystem.java:141)
	at org.apache.poi.hssf.usermodel.HSSFWorkbook.<init>(HSSFWorkbook.java:342)
	at org.apache.poi.hssf.usermodel.HSSFWorkbook.<init>(HSSFWorkbook.java:323)

问题排查

通过Google搜索找到一篇文章,https://bz.apache.org/bugzilla/show_bug.cgi?id=46391
从讨论问题记录看,出问题的原因是: Excel文件损坏,POI 找不到文件的结束符,导致下标越界:

我当时的猜想应该是文件损坏,因为这个问题毕竟是08年的时候提出来的,翻阅的bug记录,这个bug已经修复了。
后面那哥们把出测试环境解析出问题的文件发过来,我用本地的Office办公软件(Excel2013)尽然可以正常的打开。

虽说文件可以正常打开,但我还是怀疑文件有问题,后面做了进一步排查:

  • 确认服务器生成的Excel文件原本就有损坏

    后面第三方确认文件没问题,因为不止推送我们一家

  • 排查代码是否有问题

    FTP下载使用的是 commons-net,我看了下代码,就是简单的连接,打开文件流下载

通过上面的排查,还是没发现问题,我后面再想,能否通过二进制工具分析Excel文件结构是否损坏?

在我下载WinHex对二进制分析的时候,那哥们在继续测试他的代码,过了会他跟我说:“他删除了文件的最后一行保存,这个文件就能进行解析。”
我推断说,你删除一行数据,重新保存,这个时候Excel工具就修复的这个文件,所以文件又恢复正常了。

后面根据他描述的一些测试情况,我在测试服务器看了下文件列表,突然看到了一个非常有用的数据,文件的大小,我说你对比下你下载的文件的大小和FTP服务器的文件大小。

经过对比,通过程序下载的文件比原文件每个少了200-300KB,文件大小不一样,文件肯定损坏了,我说你继续检查下代码,肯定是下载代码出了问题。

最后排查代码,在FTP下载处少了一行关键代码:

// binary file
ftpClient.setFileType(FTPClient.BINARY_FILE_TYPE);

最终问题解决。

问题总结

  • Excel Cannot remove block[ xx ]; out of range[ 0 - xx ] 出现这个问题,一定是文件损坏
  • 做网络下载相关的程序,首先确保下载文件大小和原文件一样,1个字节都不能丢(这个也是我排查问题疏忽的点)
  • 做测试条件一定要保持一致,后面了解到之前在本地做测试的文件是通过FTP工具下载的
  • Excel2013比Excel2003容错性更强了,少几百KB照样可以打开,不能被表面给蒙蔽了

扩展学习

虽然问题解决了,但还留下了一个问题:能否通过二进制工具分析Excel文件结构是否损坏?
后面我通过2个二进制工具对Excel进行分析,以我目前研究的深度,没办法确认文件是否损坏。

二进制工具:WinHex,在查看class文件字节码也常被用到,工具很强大,可以通过编辑字节修改文件,详细使用方式请自行搜索。

Office 字节专用查看器 OffVis,微软官方开发:

OffVis 适用于Office2007之前的版本,对于做Excel解析非常有帮助。 对于OffVis 分析Excel字节详细解说请查看这篇文章:宏病毒研究3——病毒处理篇

OffVis 适用于Office2007之前的版本,为啥Office2007之后的版本就不适合呢?
因为在Office2007之后,xlsx 文件实际上就是个zip压缩包,结构都是通过xml的构造的。

针对 Excel xlsx 内部结构分析查看这篇文章:Excel文件XML结构

后面发现,我搜索的Excel字节相关的文章,都是与安全从业人员相关的,主要是用来分析文件是否被篡改或植入病毒。

参考

Office恶意文件解析与混淆研究
宏病毒研究3——病毒处理篇
Office文件的奥秘——.NET平台下不借助Office实现Word、Powerpoint等文件的解析(一)

转载于:https://my.oschina.net/wenjinglian/blog/2253062

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值