

本文属于机器翻译版本。若本译文内容与英语原文存在差异，则一律以英文原文为准。

# 插件 API 参考
<a name="sbomgen-plugin-api-reference"></a>

 Inspector-sbomgen Lua 插件的完整 API 参考。有关编写插件的指南，请参阅[插件开发者指南](sbomgen-plugin-developer-guide.md)。有关测试的信息，请参阅[插件测试指南](sbomgen-plugin-testing-guide.md)。

## 概述
<a name="sbomgen-plugin-api-reference-overview"></a>

 运行时提供的所有函数均可通过全局`sbomgen`表（文件 I/O、正则表达式、日志记录、常量等）进行访问。此外，每个插件都定义了一小部分顶级全局函数（`discover`、、`collect``get_scanner_name``subscribe_to_event`、等），sbomgen 在插件生命周期的定义时刻调用这些函数。这些记录在[插件生命周期全局变量](#sbomgen-plugin-api-reference-plugin-lifecycle-globals)。

 在`*_test.lua`文件中，sbomgen 还公开了一个`testing`全局变量，允许测试作者驱动发现→集合管道并做出断言。请参阅[正在测试 API](#sbomgen-plugin-api-reference-testing-api)。

### 沙盒限制
<a name="sbomgen-plugin-api-reference-sandbox-restrictions"></a>

 插件在沙箱 Lua 虚拟机中运行，标准库访问受限。有以下 Lua 标准库模块**可用**：


| **模块** | **备注** | 
| --- | --- | 
| base | 核心功能（print、type、tostring、tonumber、pairs、ipairs、pcall、、error、select、unpack、rawget、rawset、、等）。 dofile、loadfile、和已loadstring被移除。 | 
| string | 全字符串操作（string.matchstring.find、string.format、string.gsub、等） | 
| table | 全表操作（table.inserttable.remove、table.sort、table.concat、等） | 
| math | 完整的数学库（math.floormath.maxmath.min、、等） | 
| package | require()可用，但仅限于插件自己的目录树中的模块。父目录遍历 () require("../shared") 已被阻止。 package.cpath并package.path被清除。 | 

 出于安全性和稳定性考虑，**明确禁止使用**以下标准库模块：


| **模块** | **原因** | 
| --- | --- | 
| io | 直接文件系统访问已被阻止。所有文件操作都必须通过sbomgen.\*函数，这些函数通过构件接口进行路由，以实现跨对象类型（目录、容器、卷等）的一致行为。 | 
| os | 系统级操作（os.execute、os.remove、os.renameos.getenv、等）被阻止，以防止插件修改主机系统。 | 
| debug | 阻止调试库是为了防止检查或修改 Lua VM 内部结构。 | 
| coroutine | 协程未加载。 | 

 这些模块不在虚拟机的许可名单中，也无法通过插件访问。

**注意**  
**重要：**所有文件都 I/O 必须经过`sbomgen.*`函数（例如`sbomgen.read_file`、`sbomgen.open_file`、`sbomgen.get_file_list`）。使用`io.open`或任何直接访问文件系统都会引发运行时错误。`sbomgen`API 可确保插件与构件抽象层交互，无论是扫描目录、容器映像、档案还是卷，工件抽象层都能提供一致的行为。

## 插件生命周期全局变量
<a name="sbomgen-plugin-api-reference-plugin-lifecycle-globals"></a>

 插件是一个名为 Lua 的文件`init.lua`，它定义了某些顶级全局函数。这些全局变量**不**在`sbomgen`桌面上——它们是插件定义的函数，供sbomgen调用。发现插件和集合插件的有效全局变量集不同。对于下面的每个函数，如果插件省略了该函数，则使用表格中显示的默认值。

### 发现插件
<a name="sbomgen-plugin-api-reference-discovery-plugins"></a>


| **函数** | **阿里** | **必填** | **默认（省略时）** | **描述** | 
| --- | --- | --- | --- | --- | 
| discover() | 0 | 是 | — | 返回此插件找到的文件。返回路径字符串的顺序表（单事件模式）或由事件名称字符串键控的表，其值为路径表（多事件模式）。 | 
| get\_event\_name() | 0 | 否 | "lua:{platform}/{category}/{ecosystem}" | 返回发布文件所依据的事件名称。在所有发现插件中必须是唯一的。 | 
| get\_scanner\_name() | 0 | 否 | 生态系统目录名称 | 返回扫描仪的显示名称。在所有发现插件中必须是唯一的。 | 
| get\_scanner\_description() | 0 | 否 | "Lua discovery plugin: {ecosystem}" | 返回人类可读的描述。 | 
| get\_scanner\_groups() | 0 | 否 | 源自类别目录（参见开发者指南） | 返回扫描仪组字符串表。使用sbomgen.groups.\*常量。 | 
| get\_localhost\_scan\_paths() | 0 | 否 | — | 返回扫描本地主机构件时要包含的 file/directory 路径表。仅在localhost扫描时咨询。 | 

### 集合插件
<a name="sbomgen-plugin-api-reference-collection-plugins"></a>


| **函数** | **阿里** | **必填** | **默认（省略时）** | **描述** | 
| --- | --- | --- | --- | --- | 
| collect(file\_path) | 1 | 是 | — | 每个发布到已订阅事件的文件都调用一次。解析文件并通过发送调查结果。sbomgen.push\_package()不返回任何内容。 | 
| subscribe\_to\_event() | 0 | 否 | "lua:{platform}/{category}/{ecosystem}" | 返回该收集器订阅的事件名称。应与相应的发现插件相匹配get\_event\_name()。 | 
| get\_collector\_name() | 0 | 否 | 生态系统目录名称 | 返回收藏家的显示名称。在所有集合插件中必须是唯一的。 | 
| get\_collector\_description() | 0 | 否 | ""（空） | 返回人类可读的描述。 | 

## 文件 I/O
<a name="sbomgen-plugin-api-reference-file-i-o"></a>

 所有文件操作都必须通过 `sbomgen.*` API 进行。无法通过 Lua 的`io`库直接访问文件系统（请参阅[沙盒限制](#sbomgen-plugin-api-reference-sandbox-restrictions)）。`sbomgen`文件 I/O 函数通过工件接口进行路由，确保您的插件无论是扫描磁盘上的目录、容器映像、压缩存档还是已装入的卷，都能以相同的方式工作。

### `sbomgen.get_file_list()`
<a name="sbomgen-plugin-api-reference-sbomgen-get-file-list"></a>

 以字符串表的形式返回构件中的所有文件路径。
+ **返回:**`{string, ...}`— 绝对文件路径字符串表
+ **性能：**此函数将构件中的每个文件路径都作为 Lua 字符串复制到 Lua VM 中。对于大型工件（例如，包含30万多个文件的本地主机扫描），仅此一项就需要几秒钟。在 Lua 中迭代返回的表`string.match()`会增加更多的开销——完整扫描可能需要 15 秒以上。**工件中的文件越多，插件的速度就越慢。**

**注意**  
**尽可能首选以下有针对性的替代方案：**  


| **函数** | **在... 时使用** | 
| --- | --- | 
| sbomgen.find\_files\_by\_name() | 你知道要匹配的确切文件名（例如，"requirements.txt"，"curl"） | 
| sbomgen.find\_files\_by\_name\_icase() | 同上，但不区分大小写 | 
| sbomgen.find\_files\_by\_suffix() | 你需要匹配路径后缀（例如，，"/pom.properties"）"curlver.h" | 
| sbomgen.find\_files\_by\_path\_regex() | 你需要全路径正则表达式匹配 | 
| sbomgen.glob\_find\_files() | 你需要全局风格的基本名称匹配 | 
这些函数在 Lua VM 之外执行匹配，仅返回匹配的路径，即使在 300K 文件工件上也能在 1 毫秒内完成。`get_file_list()`仅当您的匹配逻辑无法用上述任何一种表达时才使用。

```
-- AVOID in discovery plugins when possible:
local files = sbomgen.get_file_list()
for _, f in ipairs(files) do
    if string.match(f, "pattern$") then ... end
end

-- PREFER:
local matches = sbomgen.find_files_by_name({"target-file.txt"})
```

### `sbomgen.read_file(path)`
<a name="sbomgen-plugin-api-reference-sbomgen-read-file-path"></a>

 读取文件的全部内容并将其作为字符串返回。
+ **退货：**`string, err`
+ 失败时：`nil, error_string`

```
local content, err = sbomgen.read_file("/app/package.json")
if err then
    sbomgen.log_error("read failed: " .. err)
    return
end
```

### `sbomgen.open_file(path)`
<a name="sbomgen-plugin-api-reference-sbomgen-open-file-path"></a>

 打开文件进行流式读取。返回一个 FileHandle 对象。对于不切实际地将全部内容加载到内存中的大型文件，请使用此选项。
+ **退货：**`FileHandle, err`

```
local fh, err = sbomgen.open_file(path)
if err then return end
local line = fh:read_line()
while line do
    -- process line
    line = fh:read_line()
end
fh:close()
```

### `sbomgen.glob_find_files(pattern)`
<a name="sbomgen-plugin-api-reference-sbomgen-glob-find-files-pattern"></a>

 返回与 `filepath.Match` Go glob 模式匹配的文件。该模式与基本文件名相匹配。
+ **退货：**`{string, ...}, err`

```
local files, err = sbomgen.glob_find_files("*.txt")
```

 `sbomgen.get_file_list()`与一起使用`string.match`可进行完整路径模式匹配。

### `sbomgen.find_files_by_name(names)`
<a name="sbomgen-plugin-api-reference-sbomgen-find-files-by-name-names"></a>

 返回其基本名称（最后一个路径组件）与给定名称之一完全匹配的文件。迭代和比较发生在 Go 中，这使得迭代和比较比在 Lua `sbomgen.get_file_list()` 中迭代要快得多。
+ **参数:**`names`— 字符串表（要匹配的基本名称）
+ **返回:**`{string, ...}`— 匹配的文件路径（无错误元组）

```
local curl_bins = sbomgen.find_files_by_name({"curl", "curl.exe"})
local headers = sbomgen.find_files_by_name({"curlver.h"})
```

### `sbomgen.find_files_by_name_icase(names)`
<a name="sbomgen-plugin-api-reference-sbomgen-find-files-by-name-icase-names"></a>

 返回基本名称与给定名称之一匹配的文件，忽略大小写。例如，`"version"`匹配`VERSION``Version`、和`version`。比如`find_files_by_name`，匹配发生在 Lua 虚拟机之外。
+ **参数:**`names`— 字符串表（要匹配的基本名称，不区分大小写）
+ **返回:**`{string, ...}`— 匹配的文件路径（无错误元组）

```
local version_files = sbomgen.find_files_by_name_icase({"version"})
local war_files = sbomgen.find_files_by_name_icase({"jenkins.war"})
```

### `sbomgen.find_files_by_suffix(suffixes)`
<a name="sbomgen-plugin-api-reference-sbomgen-find-files-by-suffix-suffixes"></a>

 返回其完整 (forward-slash-normalized) 路径以给定后缀之一结尾的文件。比如`find_files_by_name`，匹配发生在 Lua 虚拟机之外。
+ **参数:**`suffixes`— 字符串表（要匹配的路径后缀）
+ **返回:**`{string, ...}`— 匹配的文件路径（无错误元组）

```
local pom_files = sbomgen.find_files_by_suffix({"/pom.properties"})
local release_headers = sbomgen.find_files_by_suffix({"ap_release.h", "opensslv.h"})
```

### `sbomgen.find_files_by_path_regex(patterns)`
<a name="sbomgen-plugin-api-reference-sbomgen-find-files-by-path-regex-patterns"></a>

 返回 forward-slash-normalized路径与任何给定 Go (RE2) 正则表达式模式匹配的文件。匹配发生在 Lua VM 之外，这使得在大文件列表上更有效率。
+ **参数:**`patterns`— Go 正则表达式字符串表
+ **返回:**`{string, ...}`— 匹配的文件路径（无错误元组）
+ **引发：**如果任何模式无法编译，则会出现 Lua 错误

```
local configs = sbomgen.find_files_by_path_regex({"/etc/.*\\.conf$", "/opt/.*/config\\.json$"})
```

### 性能：`find_files_by_*`vs `get_file_list`
<a name="sbomgen-plugin-api-reference-performance-find-files-by-vs-get-file-list"></a>

 对于发现插件，最好使用`find_files_by_name``find_files_by_suffix`、或`find_files_by_path_regex`而不是`get_file_list()`在 Lua 中进行迭代。在包含 30 万个文件的本地主机扫描中，在 Lua 中迭代文件列表大约需要 15 `string.match()` 秒，而在 1 毫秒内`find_files_by_name`完成。不同之处在于，将每个文件路径作为字符串`get_file_list()`复制到 Lua VM 中，然后 Lua 解释每个路径的循环和模式匹配。这些`find_files_by_*`函数在 Lua VM 之外执行匹配并仅返回匹配的路径，从而避免了复制和每个路径的解释开销。

 `get_file_list()`仅当您需要无法用基本名称、后缀或正则表达式匹配表示的自定义匹配逻辑时才使用。

### `sbomgen.read_dir(path)`
<a name="sbomgen-plugin-api-reference-sbomgen-read-dir-path"></a>

 列出目录中的条目。
+ **退货：**`{{name, is_dir}, ...}, err`

```
local entries, err = sbomgen.read_dir("/app/node_modules")
if err then return end
for _, e in ipairs(entries) do
    if e.is_dir then
        sbomgen.log_debug("directory: " .. e.name)
    end
end
```

### `sbomgen.file_stat(path)`
<a name="sbomgen-plugin-api-reference-sbomgen-file-stat-path"></a>

 返回有关文件的元数据。
+ **退货：**`{is_regular, is_dir, size}, err`

```
local info, err = sbomgen.file_stat(path)
if err then return end
if info.is_regular and info.size > 0 then
    -- process file
end
```

### `sbomgen.read_zip_entry(path, entry_path)`
<a name="sbomgen-plugin-api-reference-sbomgen-read-zip-entry-path-entry-path"></a>

 从 ZIP、JAR 或 WAR 存档中读取单个条目。
+ **退货：**`string, err`

```
local manifest, err = sbomgen.read_zip_entry(
    "/app/lib/example.jar",
    "META-INF/MANIFEST.MF"
)
```

### `sbomgen.search_binary(path, regex)`
<a name="sbomgen-plugin-api-reference-sbomgen-search-binary-path-regex"></a>

 将文件解析为 ELF、PE 或 Mach-O 二进制文件，然后在默认 constant/variable 部分中搜索 Go 正则表达式匹配项。
+ **返回:**`string|nil, err`— 匹配的字符串，如果不匹配则返回 nil

```
local version, err = sbomgen.search_binary(path, "Version:\\s+([\\d.]+)")
if version then
    sbomgen.log_info("found version: " .. version)
end
```

### `sbomgen.search_binary_all(path, regex [, n])`
<a name="sbomgen-plugin-api-reference-sbomgen-search-binary-all-path-regex-n"></a>

 将文件解析为 ELF、PE 或 Mach-O 二进制文件，并返回默认部分中所有唯一的第一个捕获组匹配项。 constant/variable 通过`n`以限制结果。
+ **返回:**`{string, ...}|nil, err`— 匹配字符串表，如果没有匹配项，则返回 nil

```
local versions, err = sbomgen.search_binary_all(path, "version[= ]+([\\d.]+)", 5)
if versions then
    for _, v in ipairs(versions) do
        sbomgen.log_info("found: " .. v)
    end
end
```

### `sbomgen.search_binary_raw(path, regex)`
<a name="sbomgen-plugin-api-reference-sbomgen-search-binary-raw-path-regex"></a>

 在整个二进制文件中搜索第一个正则表达式匹配项，而不限于特定部分。在基于节的搜索 (`search_binary`) 不足时使用，例如，当版本字符串位于非标准部分时。
+ **返回:**`string|nil, err`— 匹配的字符串，如果不匹配则返回 nil

```
local version, err = sbomgen.search_binary_raw(path, "ProductVersion[\\x00\\s]+([\\d.]+)")
```

## FileHandle 方法
<a name="sbomgen-plugin-api-reference-filehandle-methods"></a>

 FileHandle 对象由返回`sbomgen.open_file()`。

### `fh:read_line()`
<a name="sbomgen-plugin-api-reference-fh-read-line"></a>

 读取下一行（不含换行符）。`nil`在 EOF 时返回。
+ **退货：**`string|nil, err`

### `fh:read(n)`
<a name="sbomgen-plugin-api-reference-fh-read-n"></a>

 读取最多`n`字节。`nil`在 EOF 时返回。
+ **退货：**`string|nil, err`

### `fh:close()`
<a name="sbomgen-plugin-api-reference-fh-close"></a>

 关闭文件句柄。完成后请务必关闭手柄。

## 二进制实用程序
<a name="sbomgen-plugin-api-reference-binary-utilities"></a>

### `sbomgen.sha256(path)`
<a name="sbomgen-plugin-api-reference-sbomgen-sha256-path"></a>

 返回文件内容的十六进制编码 SHA-256 哈希值。
+ **退货：**`string, err`

```
local hash, err = sbomgen.sha256("/app/bin/server")
if hash then
    sbomgen.log_info("SHA-256: " .. hash)
end
```

### `sbomgen.contains_bytes(path, patterns)`
<a name="sbomgen-plugin-api-reference-sbomgen-contains-bytes-path-patterns"></a>

 检查文件是否包含每个给定的字节模式。按与输入模式相同的顺序返回布尔值表。
+ **退货：**`{bool, ...}, err`

```
local results, err = sbomgen.contains_bytes(path, {
    "\xff Go buildinf:",   -- Go build identifier
    "/rustc/",             -- Rust build identifier
})
if results then
    local is_go = results[1]
    local is_rust = results[2]
end
```

### `sbomgen.get_pe_version_info(path)`
<a name="sbomgen-plugin-api-reference-sbomgen-get-pe-version-info-path"></a>

 从二进制文件中解析 Windows PE 版本资源。返回包含版本字段的表，或者`nil, err`如果该文件不是 PE 二进制文件或没有版本资源。
+ **退货：**`{product_version, file_version, string_table}, err`

 `product_version`和`file_version`字段来自 PE `FixedFileInfo` 结构，格式为`"major.minor.build.revision"`。该`string_table`字段是一个由**区域代码**键控的嵌套表（例如，`"040904B0"`对于美国英语 Unicode）。每个语言环境都映射到从 PE 中抽取的 name/value 对表`StringFileInfo`（`ProductVersion``ProductName``FileDescription`、、等）。PE 二进制文件可能会暴露一个或多个语言环境。

```
local info, err = sbomgen.get_pe_version_info(file_path)
if err then return end

-- Fixed version fields (always flat)
local product_ver = info.product_version  -- e.g. "25.1.0.0"
local file_ver    = info.file_version     -- e.g. "25.1.0.0"

-- String table — iterate locales, or address a known locale by key
for locale, fields in pairs(info.string_table or {}) do
    sbomgen.log_info(string.format("%s ProductName=%s", locale, fields.ProductName or ""))
end

-- US English Unicode is the most common locale for PE files
local us = (info.string_table or {})["040904B0"]
if us then
    local display_ver = us.ProductVersion  -- e.g. "25.01"
    local name        = us.ProductName     -- e.g. "7-Zip"
end
```

### `sbomgen.parse_product_version(path)`
<a name="sbomgen-plugin-api-reference-sbomgen-parse-product-version-path"></a>

 便捷包装器，仅返回 PE 二进制文件中的产品版本字符串。 FixedFileInfo相当于打电话`get_pe_version_info(path)`和读书`product_version`。
+ **退货：**`string, err`

```
local version, err = sbomgen.parse_product_version(file_path)
if version then
    sbomgen.log_info("product version: " .. version)
end
```

### `sbomgen.parse_file_version(path)`
<a name="sbomgen-plugin-api-reference-sbomgen-parse-file-version-path"></a>

 便捷包装器，仅返回 PE 二进制文件中的文件版本字符串。 FixedFileInfo相当于打电话`get_pe_version_info(path)`和读书`file_version`。
+ **退货：**`string, err`

```
local version, err = sbomgen.parse_file_version(file_path)
if version then
    sbomgen.log_info("file version: " .. version)
end
```

## Package 输出
<a name="sbomgen-plugin-api-reference-package-output"></a>

### `sbomgen.push_package(pkg)`
<a name="sbomgen-plugin-api-reference-sbomgen-push-package-pkg"></a>

 将软件包查找结果推送到 SBOM 中。仅在集合插件中可用。

 该`pkg`表支持以下字段：


| **字段** | **Type** | **必填** | **描述** | 
| --- | --- | --- | --- | 
| name | 字符串 | 是 | 软件包名称 | 
| version | 字符串 | 否 | 已解析的版本字符串 | 
| namespace | 字符串 | 否 | PURL 命名空间（例如，"curl"，"wordpress/plugin"） | 
| purl\_type | 字符串 | 是 | PURL 类型（例如、"pypi"、、"npm"、"cargo""deb"、"generic"） | 
| component\_type | 字符串 | 是 | CycloneDX 组件类型；使用sbomgen.component\_types.\*常量（例如）sbomgen.component\_types.LIBRARY | 
| qualifiers | 表 | 否 | PURL 限定符作为键值对（出现在软件包 URL 中） | 
| properties | 表 | 否 | CycloneDX 组件属性作为键值对（参见）[CycloneDX 属性](#sbomgen-plugin-api-reference-cyclonedx-properties) | 
| children | 表 | 否 | 嵌套子包，每个子包的形状都与pkg（递归验证必填字段） | 

```
sbomgen.push_package({
    name = "requests",
    version = "2.28.1",
    purl_type = "pypi",
    component_type = sbomgen.component_types.LIBRARY,
    qualifiers = { example_qualifier = "example_qualifier_value" },
    properties = {
        -- Use your own namespace; amazon:inspector:* is reserved for Amazon Inspector.
        ["acme:example:extra_field"] = "example_value",
    },
})
```

## CycloneDX 属性
<a name="sbomgen-plugin-api-reference-cyclonedx-properties"></a>

 CycloneDX 属性是附加到 SBOM 中组件的键值元数据。它们不同于 PURL 预选赛：
+ **`qualifiers`**— PURL 预选赛。它们成为软件包 URL 字符串的一部分（例如`pkg:deb/debian/curl@7.88.1?arch=amd64`）。一些 PURL 限定符对 Amazon Inspector 具有语义意义，会影响漏洞识别。请参阅[什么是包裹 URL？](https://docs.aws.amazon.com/inspector/latest/user/sbom-generator-purl-sbom.html) 了解检查员的每种类型的惯例。
+ **`properties`**— CycloneDX 组件属性。它们显示在 SBOM 的`components[].properties`数组中，不会更改组件的标识方式。

### 保留的命名空间
<a name="sbomgen-plugin-api-reference-reserved-namespaces"></a>

 CycloneDX 属性命名空间`amazon:inspector:*`系列是为 Amazon Inspector 保留的：
+ `amazon:inspector:sbom_generator:*`— 由 sbomgen 及其内置扫描仪使用。
+ `amazon:inspector:sbom_scanner:*`— 由 Amazon Inspector Scan API 使用。

 **插件定义的属性不得使用这些命名空间。**写入保留的命名空间可能会与 Inspector 所依赖的值发生阴影或冲突，并且在漏洞识别过程中可能会错误地解释生成的 SBOM。有关保留密钥的完整列表，请参阅在 [Amazon Inspector 中使用 CycloneDX 命名](https://docs.aws.amazon.com/inspector/latest/user/cyclonedx-namespace.html)空间。

### 密钥命名规则
<a name="sbomgen-plugin-api-reference-key-naming-rules"></a>

 传递给的属性键`sbomgen.push_package()`的处理方式如下：


| **输入键** | **SBOM 中生成的密钥** | **推荐用于自定义插件？** | 
| --- | --- | --- | 
| 包含:（例如，acme:my\_plugin:field） | 逐字使用 | 是 — 将所有插件定义的属性放在你自己的命名空间中 | 
| 否:（例如，field） | 自动添加前缀为 amazon:inspector:sbom\_generator:field | 不是 — 这会写入保留的命名空间 | 

 请务必在您定义的属性键中至少包含一个冒号。使用您的组织或插件独有的命名空间（例如`acme:python-pip:*`）：

```
properties = {
    -- Custom namespace — safe to use (recommended)
    ["acme:python-pip:manifest_path"] = file_path,
    ["acme:python-pip:pinned"]        = "true",

    -- Fully-qualified key outside amazon:inspector:* — also fine
    ["my:custom:namespace:key"] = "value",

    -- No colon: avoid — ends up as "amazon:inspector:sbom_generator:custom_field"
    -- custom_field = "value",
}
```

### 由 sbomgen 设置的属性
<a name="sbomgen-plugin-api-reference-properties-set-by-sbomgen"></a>

 Sbomgen 可以将自己的属性附加到它发出的每个组件上。这些值来自保留的`amazon:inspector:sbom_generator:*`命名空间，不应由插件生成。观察到的运行时行为：
+ `source_path`总是由 sbomgen 添加的。
+ `source_file_scanner`并在启用`source_package_collector``--enable-debug-props`时添加。

 Amazon Inspector 用户指南：将 Cy [cloneDX 命名空间与 Amazon Inspector 一起使用](https://docs.aws.amazon.com/inspector/latest/user/cyclonedx-namespace.html)。

## 属性常量
<a name="sbomgen-plugin-api-reference-property-constants"></a>

 内置的属性键常量可通过`sbomgen.properties`获得。下面的每个常量都解析为保留`amazon:inspector:sbom_generator:*`命名空间内的一个密钥。这些常量的存在是为了让 sbomgen 的内置扫描器发出一致的属性键。**它们不是自定义插件的扩展点——在自定义插件**中使用它们会写入保留的命名空间，而 Inspector 可以依赖这些值。见[保留的命名空间](#sbomgen-plugin-api-reference-reserved-namespaces)上文。

 例如`acme:my_plugin:*`，自定义插件作者应在自己的命名空间下定义属性，而不是重复使用这些常量。


| **常量** | **已解析值** | 
| --- | --- | 
| sbomgen.properties.NAMESPACE | amazon:inspector:sbom\_generator: | 
| sbomgen.properties.VENDOR | amazon:inspector:sbom\_generator:vendor | 
| sbomgen.properties.FILE\_SIZE\_BYTES | amazon:inspector:sbom\_generator:file\_size\_bytes | 
| sbomgen.properties.KERNEL\_COMPONENT | amazon:inspector:sbom\_generator:kernel\_component | 
| sbomgen.properties.RUNNING\_KERNEL | amazon:inspector:sbom\_generator:running\_kernel | 
| sbomgen.properties.UNRESOLVED\_VERSION | amazon:inspector:sbom\_generator:unresolved\_version | 
| sbomgen.properties.TRANSITIVE\_DEPENDENCY | amazon:inspector:sbom\_generator:experimental:transitive\_dependency | 
| sbomgen.properties.GO\_REPLACE\_DIRECTIVE | amazon:inspector:sbom\_generator:replaced\_by | 
| sbomgen.properties.DUPLICATE\_PACKAGE | amazon:inspector:sbom\_generator:is\_duplicate\_package | 
| sbomgen.properties.DUPLICATE\_PURL | amazon:inspector:sbom\_generator:duplicate\_purl | 
| sbomgen.properties.DOCKERFILE\_CHECK | amazon:inspector:sbom\_generator:dockerfile\_finding | 
| sbomgen.properties.CERTIFICATE\_FINDING | amazon:inspector:sbom\_generator:certificate\_finding | 
| sbomgen.properties.CERTIFICATE\_SUBJECT\_NAME | amazon:inspector:sbom\_generator:certificate:subject\_name | 
| sbomgen.properties.CERTIFICATE\_ISSUER\_NAME | amazon:inspector:sbom\_generator:certificate:issuer\_name | 
| sbomgen.properties.CERTIFICATE\_SIGNATURE\_ALGORITHM | amazon:inspector:sbom\_generator:certificate:signature\_algorithm | 
| sbomgen.properties.CERTIFICATE\_NOT\_VALID\_BEFORE | amazon:inspector:sbom\_generator:certificate:not\_valid\_before | 
| sbomgen.properties.CERTIFICATE\_NOT\_VALID\_AFTER | amazon:inspector:sbom\_generator:certificate:not\_valid\_after | 
| sbomgen.properties.WINDOWS\_REGISTRY\_KEY | amazon:inspector:sbom\_generator:registry\_key | 
| sbomgen.properties.SUBSCRIPTION\_ENABLED | amazon:inspector:sbom\_generator:subscription:enabled | 
| sbomgen.properties.SUBSCRIPTION\_NAME | amazon:inspector:sbom\_generator:subscription:name | 
| sbomgen.properties.SUBSCRIPTION\_LOCKED\_VERSION | amazon:inspector:sbom\_generator:subscription:locked\_version | 
| sbomgen.properties.OPENSSL\_FULL\_VERSION | amazon:inspector:sbom\_generator:openssl:full\_version | 
| sbomgen.properties.HARDENED\_IMAGE\_VENDOR | amazon:inspector:sbom\_generator:hardened\_image:vendor | 

## 扫描仪组
<a name="sbomgen-plugin-api-reference-scanner-groups"></a>

 发现插件必须通过声明其扫描器组`get_scanner_groups()`。群组对扫描仪进行分类，并允许用户有选择地启用或禁用类别。常量可通过以下方式`sbomgen.groups`获得：


| **常量** | **值** | **描述** | 
| --- | --- | --- | 
| sbomgen.groups.OS | "os" | 操作系统包管理器（dpkg、rpm 等） | 
| sbomgen.groups.PROGRAMMING\_LANGUAGE | "programming-language-packages" | 语言包管理器（pip、npm、maven 等） | 
| sbomgen.groups.BINARY | "binary" | 编译后的二进制分析（Go、Rust） | 
| sbomgen.groups.PACKAGE\_COLLECTOR | "pkg-scanner" | 一般包裹集合 | 
| sbomgen.groups.EXTRA\_ECOSYSTEMS | "extra-ecosystems" | 其他生态系统（curl、nginx 等） | 
| sbomgen.groups.CERTIFICATE | "certificate" | 证书扫描 | 
| sbomgen.groups.CUSTOM | "custom" | 自动添加到通过加载的所有自定义插件中 --plugin-dir | 
| sbomgen.groups.MACHINE\_LEARNING | "machine-learning" | 机器学习模型检测 | 

 示例：

```
function get_scanner_groups()
    return {sbomgen.groups.PROGRAMMING_LANGUAGE, sbomgen.groups.PACKAGE_COLLECTOR}
end
```

## 组件类型常量
<a name="sbomgen-plugin-api-reference-component-type-constants"></a>

 中的`component_type`字段`push_package()`必须是 CycloneDX 1.5 组件类型之一。常量可通过以下方式`sbomgen.component_types`获得：


| **常量** | **值** | 
| --- | --- | 
| sbomgen.component\_types.APPLICATION | "application" | 
| sbomgen.component\_types.FRAMEWORK | "framework" | 
| sbomgen.component\_types.LIBRARY | "library" | 
| sbomgen.component\_types.CONTAINER | "container" | 
| sbomgen.component\_types.PLATFORM | "platform" | 
| sbomgen.component\_types.OPERATING\_SYSTEM | "operating-system" | 
| sbomgen.component\_types.DEVICE | "device" | 
| sbomgen.component\_types.DEVICE\_DRIVER | "device-driver" | 
| sbomgen.component\_types.FIRMWARE | "firmware" | 
| sbomgen.component\_types.FILE | "file" | 
| sbomgen.component\_types.MACHINE\_LEARNING\_MODEL | "machine-learning-model" | 
| sbomgen.component\_types.DATA | "data" | 

 示例：

```
sbomgen.push_package({
    name = "requests",
    version = "2.28.1",
    purl_type = "pypi",
    component_type = sbomgen.component_types.LIBRARY,
})
```

## 平台常量
<a name="sbomgen-plugin-api-reference-platform-constants"></a>

 用于比较`sbomgen.get_platform()`的常量。可通过`sbomgen.platform`以下方式获得：


| **常量** | **值** | 
| --- | --- | 
| sbomgen.platform.LINUX | "linux" | 
| sbomgen.platform.WINDOWS | "windows" | 
| sbomgen.platform.DARWIN | "darwin" | 

 示例：

```
if sbomgen.get_platform() == sbomgen.platform.WINDOWS then
    -- Windows-specific logic
end
```

## Artication
<a name="sbomgen-plugin-api-reference-artifact-info"></a>

### `sbomgen.get_platform()`
<a name="sbomgen-plugin-api-reference-sbomgen-get-platform"></a>

 返回运行时平台字符串（例如`"linux"`、`"windows"`、`"darwin"`）。

### `sbomgen.get_artifact_type()`
<a name="sbomgen-plugin-api-reference-sbomgen-get-artifact-type"></a>

 返回正在扫描的工件的类型（例如`"directory"`，`"archive"`）。

### `sbomgen.should_collect_licenses()`
<a name="sbomgen-plugin-api-reference-sbomgen-should-collect-licenses"></a>

 `true`如果用户通过启用了许可证收集，则返回`--collect-licenses`。

### `sbomgen.get_env_vars()`
<a name="sbomgen-plugin-api-reference-sbomgen-get-env-vars"></a>

 以`{key, value}`条目表的形式返回工件中的环境变量。

```
local env_vars = sbomgen.get_env_vars()
for _, env in ipairs(env_vars) do
    if env.key == "NODE_ENV" then
        sbomgen.log_info("Node environment: " .. env.value)
    end
end
```

### `sbomgen.get_system_drive()`
<a name="sbomgen-plugin-api-reference-sbomgen-get-system-drive"></a>

 从构件的环境中返回系统驱动器号（例如`"C:"`）。读取`SystemDrive`环境变量，`"C:"`如果未设置，则默认为。这相当于 Lua。`strutils.GetSystemDriverLetter()`

```
local drive = sbomgen.get_system_drive()
local program_files = drive .. "/Program Files/"
```

## 系统信息
<a name="sbomgen-plugin-api-reference-system-info"></a>

 这些函数返回有关工件操作系统和硬件的元数据。如果信息不可用（例如，扫描没有操作系统元数据的目录时），则值可能为空字符串。


| **函数** | **返回值** | 
| --- | --- | 
| sbomgen.get\_os\_name() | 操作系统名称（例如"Ubuntu"、"Alpine Linux"） | 
| sbomgen.get\_os\_version() | 操作系统版本（例如，"22.04"，"3.18"） | 
| sbomgen.get\_os\_codename() | 操作系统代号（例如，，"jammy"）"bookworm" | 
| sbomgen.get\_os\_id() | 操作系统标识符（例如"ubuntu"，"alpine"） | 
| sbomgen.get\_kernel\_name() | 内核名称（例如"Linux"） | 
| sbomgen.get\_kernel\_version() | 内核版本字符串 | 
| sbomgen.get\_cpu\_arch() | CPU 架构（例如，"x86\_64"，"aarch64"） | 
| sbomgen.get\_hostname() | 系统的主机名 | 

## 正则表达式
<a name="sbomgen-plugin-api-reference-regular-expressions"></a>

 Lua 的内置模式缺少交替 (`|`)、量词范围 (`{n,}`) 和前瞻等功能。为了缩小这一差距，sbomgen 直接暴露了 Go 的软件包。`regexp`这些函数使用 Go 正则表达式语法 (RE2)，而不是 Lua 模式。

### `sbomgen.regex_find(str, pattern)`
<a name="sbomgen-plugin-api-reference-sbomgen-regex-find-str-pattern"></a>

 返回 Go 正则表达式模式的第一个匹配项，或者`nil`如果没有匹配则返回。
+ **退货：**`string|nil, err`

```
local version = sbomgen.regex_find(content, "\\d+\\.\\d+\\.\\d+")
```

### `sbomgen.regex_match(str, pattern)`
<a name="sbomgen-plugin-api-reference-sbomgen-regex-match-str-pattern"></a>

 返回第一个匹配的捕获组。索引 1 为完整匹配，2\+ 为捕获组。
+ **退货：**`{string, ...}|nil, err`

```
local groups = sbomgen.regex_match(content, "(MySQL|MariaDB) (\\d+)\\.(\\d+)\\.(\\d+)")
if groups then
    local db_type = groups[2]   -- "MySQL" or "MariaDB"
    local major   = groups[3]
end
```

### `sbomgen.regex_find_all(str, pattern [, n])`
<a name="sbomgen-plugin-api-reference-sbomgen-regex-find-all-str-pattern-n"></a>

 返回所有不重叠的匹配项。通过`n`以限制结果（默认值：全部）。
+ **退货：**`{string, ...}|nil, err`

```
local versions = sbomgen.regex_find_all(content, "\\d+\\.\\d+\\.\\d+")
```

### `sbomgen.regex_replace(str, pattern, replacement)`
<a name="sbomgen-plugin-api-reference-sbomgen-regex-replace-str-pattern-replacement"></a>

 替换所有匹配项。替换字符串可以使用`$1``$2`、等作为捕获组引用。
+ **退货：**`string, err`

```
local cleaned = sbomgen.regex_replace(raw_version, "(1[6-9]\\d{8,}|buildkitsandbox.*)$", "")
```

### 何时使用正则表达式与 Lua 模式
<a name="sbomgen-plugin-api-reference-when-to-use-regex-vs-lua-patterns"></a>

 使用 Lua 的内置 `string.match` /来`string.find`制作简单的模式 — 它们速度更快，不需要转义反斜杠。需要`sbomgen.regex_*`时使用：
+ 交替：`(foo|bar)`
+ 量词范围：`\d{8,}`
+ 复杂的字符类无法在 Lua 模式中表达

## 结构化解析
<a name="sbomgen-plugin-api-reference-structured-parsing"></a>

 Sbomgen 公开了用于将结构化文本格式直接解码为 Lua 表的轻量级助手。

### `sbomgen.json_decode(str)`
<a name="sbomgen-plugin-api-reference-sbomgen-json-decode-str"></a>

 将 JSON 字符串解析为 Lua 表。
+ **退货：**`table|nil, err`

```
local doc, err = sbomgen.json_decode('{"name":"requests","version":"2.28.1"}')
if err then return end
sbomgen.log_info(doc.name)
```

### `sbomgen.xml_decode(str)`
<a name="sbomgen-plugin-api-reference-sbomgen-xml-decode-str"></a>

 将 XML 字符串解析为 Lua 表。
+ **退货：**`table|nil, err`

 XML 值使用以下形状：
+ `_name`— 元素名称
+ `_attr`— 属性表（如果存在）
+ `_text`— 修剪后的文本内容（如果存在）
+ 数字索引 `1..n`-子元素

```
local doc, err = sbomgen.xml_decode('<package id="Newtonsoft.Json" version="13.0.3" />')
if err then return end
sbomgen.log_info(doc._attr.id)
```

## Windows 注册表
<a name="sbomgen-plugin-api-reference-windows-registry"></a>

 这些函数提供对 Windows 注册表的只读访问权限。在非 Windows 构件上，`registry_open_key`返回错误。注册表访问器在首次使用时会延迟初始化，并且支持实时 Windows API 访问（在 Windows 上进行本地主机扫描）和基于文件的 REGF 配置单元解析（容器/卷扫描）。

### `sbomgen.registry_open_key(path)`
<a name="sbomgen-plugin-api-reference-sbomgen-registry-open-key-path"></a>

 打开注册表项。返回必须用其关闭的密钥手柄`registry_close`。
+ **退货：**`key, err`

```
local key, err = sbomgen.registry_open_key("SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Uninstall\\7-Zip")
if err then return end
-- use key...
sbomgen.registry_close(key)
```

### `sbomgen.registry_get_string(key, value_name)`
<a name="sbomgen-plugin-api-reference-sbomgen-registry-get-string-key-value-name"></a>

 从打开的注册表项中读取字符串值。
+ **退货：**`string, err`

```
local version, err = sbomgen.registry_get_string(key, "DisplayVersion")
```

### `sbomgen.registry_get_integer(key, value_name)`
<a name="sbomgen-plugin-api-reference-sbomgen-registry-get-integer-key-value-name"></a>

 从打开的注册表项中读取整数值。
+ **退货：**`number, err`

### `sbomgen.registry_get_strings(key, value_name)`
<a name="sbomgen-plugin-api-reference-sbomgen-registry-get-strings-key-value-name"></a>

 从打开的注册表项中读取多字符串 (REG\_MULTI\_SZ) 值。返回字符串表。
+ **退货：**`{string, ...}, err`

```
local paths, err = sbomgen.registry_get_strings(key, "DependsOnService")
if paths then
    for _, p in ipairs(paths) do
        sbomgen.log_info("depends on: " .. p)
    end
end
```

### `sbomgen.registry_get_subkeys(key)`
<a name="sbomgen-plugin-api-reference-sbomgen-registry-get-subkeys-key"></a>

 返回打开的注册表项下的所有子项名称。
+ **退货：**`{string, ...}, err`

```
local subkeys, err = sbomgen.registry_get_subkeys(key)
for _, name in ipairs(subkeys) do
    local subkey, err = sbomgen.registry_open_key(parent_path .. "\\" .. name)
    -- ...
end
```

### `sbomgen.registry_close(key)`
<a name="sbomgen-plugin-api-reference-sbomgen-registry-close-key"></a>

 关闭注册表项句柄。垃圾回收器也会自动关闭密钥句柄，但建议明确关闭。

## 日志记录
<a name="sbomgen-plugin-api-reference-logging"></a>

 日志消息将写入 sbomgen 的控制台输出中。插件发出的每条消息都会自动以插件的源标签和生态系统为前缀，例如：

```
[custom:python-pip] Parsing requirements.txt
```

 `log_info`、`log_warn`，并`log_error`始终打印。 `log_debug`仅在使用调用 sbomgen 时才会打印。`--verbose`


| **函数** | **级别** | **默认情况下可见？** | 
| --- | --- | --- | 
| sbomgen.log\_debug(message) | 调试 | 否 — 需要 --verbose | 
| sbomgen.log\_info(message) | INFO | 是 | 
| sbomgen.log\_warn(message) | 警告 | 是 | 
| sbomgen.log\_error(message) | ERROR | 是 | 

 `string.format`用于格式化消息：

```
sbomgen.log_info(string.format("found %d packages in %s", count, file_path))
```

## 调试函数
<a name="sbomgen-plugin-api-reference-debugging-functions"></a>

### `sbomgen.breakpoint(message)`
<a name="sbomgen-plugin-api-reference-sbomgen-breakpoint-message"></a>

 打印`message`到 stderr 并阻止执行，直到用户按下 Enter。如果省略，`message`则打印一条默认消息。

 将其用作粗略的调试器，方法是在插件的关键点放置断点，然后运行`--verbose`以查看周围的日志输出。

```
sbomgen.log_info("state: " .. some_variable)
sbomgen.breakpoint("paused after state dump — press Enter to continue")
```

## 正在测试 API
<a name="sbomgen-plugin-api-reference-testing-api"></a>

 全局`testing`表下的函数仅在加载的插件测试文件 (`*_test.lua`) 中可用`inspector-sbomgen plugin test`。它们在运行时在发现或集合插件中不可用。完整的 `sbomgen.*` API 也可以在测试文件中找到，但是需要构件的`sbomgen.*`函数（例如`sbomgen.read_file()`）只有在扫描内部调用时才会产生有意义的结果。有关叙事指南，请参阅[插件测试指南](sbomgen-plugin-testing-guide.md)。

### 扫描功能
<a name="sbomgen-plugin-api-reference-scan-functions"></a>

 每个扫描函数都会创建一个给定类型的工件，针对它运行当前插件的 discovery→collection 管道，然后返回结果结果。`path`参数是相对于测试文件的目录进行解析的。


| **函数** | **Artical 那种** | 
| --- | --- | 
| testing.scan\_directory(path) | 目录 | 
| testing.scan\_archive(path) | 目录（的别名scan\_directory） | 
| testing.scan\_localhost(path) | 本地主机 | 
| testing.scan\_binary(path) | 二元 | 
| testing.scan\_volume(path) | 卷 | 
| testing.scan\_container(path) | Container | 

 所有六个都返回一个结果表，其形状如下所示。

### 结果形状
<a name="sbomgen-plugin-api-reference-result-shape"></a>

 每个查找结果表仅投影下面列出的字段。特别是，`namespace`并且`purl_type`不是单独投影的——它们被合并到完整的`purl`字符串中。

```
local result = testing.scan_directory("_testdata/example")
-- result.findings                        -- array of finding tables
-- result.findings[i].name                -- string
-- result.findings[i].version             -- string
-- result.findings[i].component_type      -- string
-- result.findings[i].purl                -- string (the full Package URL, or "" if none)
-- result.findings[i].properties          -- table<string, string>
-- result.findings[i].children            -- array of finding tables (same shape, recursive)
```

### 断言
<a name="sbomgen-plugin-api-reference-assertions"></a>


| **函数** | **签名** | **描述** | 
| --- | --- | --- | 
| testing.assert\_equals | (expected: any, actual: any, message?: string) | 如果出现则失败tostring(expected) \~= tostring(actual)。 | 
| testing.assert\_not\_equals | (expected: any, actual: any, message?: string) | 如果出现则失败tostring(expected) == tostring(actual)。 | 
| testing.assert\_true | (value: any, message?: string) | 如果value为false或则失败nil。 | 
| testing.assert\_false | (value: any, message?: string) | 如果不valuefalse是，则失败nil。 | 
| testing.assert\_nil | (value: any, message?: string) | 如果不value是，则失败nil。 | 
| testing.assert\_not\_nil | (value: any, message?: string) | 如果value是则失败nil。 | 
| testing.assert\_contains | (haystack: string, needle: string, message?: string) | 如果haystack不包含needle（子字符串匹配），则失败。 | 
| testing.assert\_matches | (str: string, pattern: string, message?: string) | 如果与给定的 Go (RE2) 正则表达式str不匹配，则失败。 | 
| testing.assert\_length | (tbl: table, expected: integer, message?: string) | 如果\#tbl不等于，则失败expected。 | 

### 控制流
<a name="sbomgen-plugin-api-reference-control-flow"></a>


| **函数** | **签名** | **描述** | 
| --- | --- | --- | 
| testing.fail | (message: string) | 使用给定消息立即使当前测试失败。 | 
| testing.skip | (message: string) | 跳过当前测试。结果被报告为已跳过，而不是失败。 | 

### 测试发现
<a name="sbomgen-plugin-api-reference-test-discovery"></a>

 文件匹配`test_`中名称以开头的任何全局 Lua 函数`*_test.lua`都被视为测试。测试文件必须位于正常`{phase}/{platform}/{category}/{ecosystem}/`深度旁边。`init.lua`夹具数据位于测试文件`_testdata/`旁边，运行器在搜索测试文件`_testdata/`时不会进入测试文件。

## 错误处理
<a name="sbomgen-plugin-api-reference-error-handling"></a>

 可能失败的 API 函数返回两个值:`value, err`. 成功时，`err`是`nil`。失败时，第一个值为`nil`且`err`为错误字符串。

```
local content, err = sbomgen.read_file(path)
if err then
    sbomgen.log_error("failed to read " .. path .. ": " .. err)
    return
end
-- content is safe to use here
```

 如果插件引发未处理的 Lua 错误，sbomgen 会记录警告，然后继续处理下一个文件或插件。其他插件不受影响。