定义
libyaml 是一个以 C 语言实现的 YAML 解析器与生成器库, 按 YAML 1.1 规范处理数据。它对外暴露的是解析器(Parser)与发射器(Emitter)两个处理器: 前者把输入的字节流转换成一系列解析事件, 后者接收事件序列并输出字节流[2]。两者互为逆过程, 任何由合法文档解析得到的事件序列都应能被发射器接受, 并还原出等价的文档[2]。
该库以 MIT 许可证发布, 源码托管在其官方代码仓库中, 包名有时简写为 yaml[3][4]。在多数 Linux 发行版中, 它被拆分为运行库包、开发包与文档包分别提供。
原理
libyaml 的解析流程是分层的。底层先从输入中读取字节并按 UTF-8 或 UTF-16 解码, 随后由扫描器(Scanner)逐个产出记号(Token), 再由解析器把这些记号组织成事件[5]。事件类型包括流开始与结束、文档开始与结束、别名、标量、序列开始与结束、映射开始与结束, 合法的事件序列需要满足一定的嵌套语法[2]。
在事件模型中, 单调的事件流可以用状态机的状态转移表示: 解析器维护一个解析状态栈, 遇到块序列、块映射、流序列、流映射等结构时压栈, 结构结束时出栈[2]。调用方循环调用解析接口, 每次取出一个事件并处理, 直到收到流结束事件; 每个事件处理完成后需要显式释放其占用的内存[6]。发射器方向则要求调用方按固定的顺序送入事件: 流开始、文档开始、内容、文档结束、流结束[6]。
发展历程
libyaml 的早期开发记录可追溯到 2006 年 5 月, 作者 Kirill Simonov 在该月先后加入头文件原型、autoconf 构建骨架, 并在随后几个月里逐步完成解码、扫描器与解析器[7]。该项目是为 Python 软件基金会(Python Software Foundation)开发的, 属于 Google Summer of Code 的一部分, 由 Clark Evans 担任导师, 采用 MIT 许可证发布[3]。0.0.1 版本在 2006 年 9 月被纳入 NetBSD 的 pkgsrc 软件集合[8]。
此后版本节奏较为平缓: 2007 年 10 月升级到 0.1.1, 2009 年 3 月到 0.1.2, 2011 年 5 月到 0.1.4, 2014 年 4 月到 0.1.6[8]。早期作者曾在公开讨论中提到, 当时库的开发一度处于停滞状态, 后续计划在完成学业后继续推进[9]。2017 年起项目转由 YAML 社区维护, 2020 年 6 月发布 0.2.5 版本, 由 Ingy döt Net 等人负责维护[10]。
应用
libyaml 被广泛用作其他语言 YAML 实现的底层引擎。Python 的 PyYAML 通过 C 扩展调用它, Ruby 的标准 YAML 库 Psych、Perl 的 YAML::XS 以及 PHP 的 yaml 扩展也都以它为基础[1]。在 Debian 等发行版中, 它以 libyaml-0-2 等二进制包名分发, 供上层软件链接使用。
在 C 程序中使用时, 开发者通常从系统包管理器安装开发包, 然后链接 yaml 库并包含 yaml.h 头文件[6]。典型的解析写法是初始化解析器、设置输入、循环读取事件, 再按事件类型自行把值搬入自定义的数据结构[6]。除事件接口外, 库还提供文档接口, 可一次性把整个文档加载成节点树, 遍历起来更方便但会分配整棵树的内存[6]。
局限
libyaml 的职责范围有意收窄。隐式标签解析、表示树的组装与序列化, 以及本地对象的构造与表示, 都不在库的设计范围之内, 需要由应用和语言绑定自行实现[2]。它面向 YAML 1.1 实现, 因此部分取值在类型判定上会与 YAML 1.2 的处理结果不同[6]。此外, 它不会把 YAML 自动映射到 C 结构体上, 标量类型也不会自动推断, 数值需要调用方自行转换并处理错误[6]。
在处理不可信输入时需要额外注意。由于 YAML 的别名机制可以让很小的文件描述出很大的数据树, 因此需要对输入规模加以限制[6]。安全方面也有过公开记录: 0.1.5 与 0.1.6 版本的 scanner.c 存在因换行导致的断言失败问题, 可造成拒绝服务, 编号为 CVE-2014-9130, 后在 0.1.6-3 中修复[11][12]。
参见
参考资料
- libyaml¶ [引用日期2026-10-14]
- LibYAML [引用日期2026-10-14]
- textproc/libyaml - The NetBSD Packages Collection [引用日期2026-10-14]
- libyaml-0.2.5-14.fc41.src | RPM Info [引用日期2026-10-14]
- mit.edu 上的网页 [引用日期2026-10-14]
- Parse and Write YAML in C | MojoAuth Dev Guides [引用日期2026-10-14]
- andersk Git - libyaml.git/history [引用日期2026-10-14]
- distinfo [引用日期2026-10-14]
- bugreport [引用日期2026-10-14]
- sourceforge.net 上的网页 [引用日期2026-10-14]
- CVE-2014-9130 [引用日期2026-10-14]
- CVE-2014-9130 | Ubuntu [引用日期2026-10-14]