【问题标题】:Is giflib 5.1.2 not thread-safe?giflib 5.1.2 不是线程安全的吗?
【发布时间】:2016-07-17 12:31:07
【问题描述】:

我正在使用 giflib,并发现如果我在关闭前一个文件之前打开一个新文件,一切都会崩溃。

  1. DGifOpen(文件 A)
  2. DGifSlurp(文件 A)
  3. DGifOpen(文件 B)
  4. DGifSlurp(文件 B)- D_GIF_ERR_READ_FAILED 失败

这很了不起,因为我可以使用自定义读取函数验证每次读取都成功并返回请求的字节数。

但是……

  1. DGifOpen(文件 A)
  2. DGifSlurp(文件 A)
  3. DGifClose(文件 A)
  4. DGifOpen(文件 B)
  5. DGifSlurp(文件 B)- 有效!

文档说 giflib 是re-entrant and thread-safe

那么,如果有多个打开的文件有什么关系呢? GifFileType 应该封装所有状态;并且文件 A 和文件 B 的用户端数据结构之间没有重叠。


更新和相关问题:giflib 是否旨在安全地处理恶意输入文件,或者它是该场景的错误工具?我在测试系统中没有看到任何自动使用 valgrind,而且我似乎找不到该项目的 CI 服务器。


更新:这与重叠文件无关,而是因为 giflib 5.1.2 仅在堆归零时才有效 - 未初始化的读取导致失败。重叠读取只是一种触发方式 那。

要重现,请下载 giflib 5.1.2,然后

  1. 运行./autogen.sh
  2. 运行make check
  3. 然后cd util && cat ../pic/porsche.gif | valgrind .libs/lt-gifsponge
  4. 观察 valgrind 报告未初始化的读取。

【问题讨论】:

    标签: c gif giflib


    【解决方案1】:

    我是 giflib 的维护者,也是 DGifSlurp() 入口点的原作者。

    4.x 和 5.x 之间的重大变化是从库中消除了静态存储。旧 API 无法重入,因为图像状态有一些静态指针。

    您正确使用了 API,重叠的多次打开应该可以工作。但实现中可能存在错误 - 代码非常陈旧,其中一些已经 20 年没有仔细研究过。

    我会在这方面与您合作。首先要做的是找出错误被抛出的位置;有 14 个不同的出口可以设置该代码。

    【讨论】:

    • 谢谢!我正在设置一个失败的测试。
    • 看起来涉及堆损坏,所以可能不是 giflib 的错,只是巧合。它在某个测试套件中以特定顺序 100% 可重复,但在其他地方则不行。
    • 实际上不是堆损坏。 -> DGifSetupDecompress、DGifG​​etImageDesc、DGifSlurp 中的“条件跳转或移动取决于未初始化的值”。
    • 原来我的测试不需要。运行make check,然后运行cd util,然后运行cat ../pic/porsche.gif | valgrind .libs/lt-gifsponge,查看未初始化的读取。
    • 试试我刚发货的5.1.4版本。将一些 malloc 更改为 calloc 可能已经消除了这个问题。
    猜你喜欢
    • 2014-02-07
    • 2010-10-15
    • 1970-01-01
    • 1970-01-01
    • 2021-10-12
    • 2015-04-18
    • 2011-10-07
    • 2012-03-02
    • 2011-10-28
    相关资源
    最近更新 更多