Skip to content

Commit f32b920

Browse files
committed
docs: 添加详细的CPE验证及标准化方法中文注释
1 parent 3faf8ca commit f32b920

File tree

1 file changed

+217
-6
lines changed

1 file changed

+217
-6
lines changed

validation.go

Lines changed: 217 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,9 @@ import (
66
"strings"
77
)
88

9+
// CPE包实现了通用平台枚举(Common Platform Enumeration)标准的解析、验证和格式化功能。
10+
// 本包支持CPE 2.3规范,提供了CPE字符串的解析、验证、标准化以及不同格式间的转换功能。
11+
912
// CPE 2.3规范中定义的字符集和限制
1013
var (
1114
// 有效URI字符集
@@ -59,7 +62,33 @@ var (
5962
// Set of illegal characters in CPE components
6063
var illegalChars = []rune{'!', '@', '#', '$', '%', '^', '&', '(', ')', '{', '}', '[', ']', '|', '\\', ';', '"', '\'', '<', '>', '?'}
6164

62-
// ValidateComponent validates the component value based on the component name
65+
// ValidateComponent 验证CPE组件值是否符合规范要求
66+
//
67+
// 功能描述:
68+
// - 验证CPE组件值是否符合CPE 2.3标准规范的要求
69+
// - 检查组件值中是否包含非法字符或控制字符
70+
// - 支持特殊值"*"(ANY)和"-"(NA)的验证
71+
//
72+
// 参数:
73+
// - value string: 要验证的组件值,可以为空字符串、特殊值或普通字符串
74+
// - componentName string: 组件名称,用于错误消息中标识哪个组件出现问题
75+
//
76+
// 返回值:
77+
// - error: 如果验证通过返回nil,否则返回包含错误详情的error对象
78+
//
79+
// 错误处理:
80+
// - 当组件值包含非法字符时,返回InvalidAttributeError
81+
// - 当组件值包含ASCII范围外的控制字符时,返回InvalidAttributeError
82+
//
83+
// 示例:
84+
//
85+
// err := ValidateComponent("windows", "ProductName") // 返回nil
86+
// err := ValidateComponent("*", "Version") // 返回nil (特殊值)
87+
// err := ValidateComponent("product#1", "ProductName") // 返回错误,因为#是非法字符
88+
//
89+
// 注意:
90+
// - 空字符串被视为有效值(通配符)
91+
// - 此函数不验证值的语义正确性,只验证字符的合法性
6392
func ValidateComponent(value string, componentName string) error {
6493
// 空字符串被视为通配符
6594
if value == "" {
@@ -88,7 +117,46 @@ func ValidateComponent(value string, componentName string) error {
88117
return nil
89118
}
90119

91-
// ValidateCPE validates the CPE object
120+
// ValidateCPE 验证CPE对象的所有字段是否符合CPE 2.3规范
121+
//
122+
// 功能描述:
123+
// - 全面验证CPE对象的完整性和有效性
124+
// - 检查必填字段(Part、Vendor、ProductName)是否存在
125+
// - 验证Part字段是否为有效值(a、h、o或*)
126+
// - 对每个组件字段调用ValidateComponent进行详细验证
127+
//
128+
// 参数:
129+
// - cpe *CPE: 待验证的CPE对象指针,可以为nil
130+
//
131+
// 返回值:
132+
// - error: 如果验证通过返回nil,否则返回具体错误信息
133+
//
134+
// 错误处理:
135+
// - 当cpe为nil时,返回InvalidFormatError
136+
// - 当Part字段为空时,返回"Part cannot be empty"错误
137+
// - 当Part值不合法时,返回InvalidPartError
138+
// - 当Vendor字段为空(除特殊测试用例外)时,返回"Vendor cannot be empty"错误
139+
// - 当ProductName字段为空时,返回"ProductName cannot be empty"错误
140+
// - 当任何组件字段包含非法字符时,返回相应的InvalidAttributeError
141+
//
142+
// 特殊处理:
143+
// - 对于ProductName="windows"且Vendor=""的特殊测试用例,允许Vendor为空
144+
//
145+
// 示例:
146+
//
147+
// cpe := &CPE{
148+
// Part: PartType{ShortName: "a"},
149+
// Vendor: "microsoft",
150+
// ProductName: "windows",
151+
// Version: "10"
152+
// }
153+
// err := ValidateCPE(cpe) // 返回nil
154+
//
155+
// invalidCpe := &CPE{Part: PartType{ShortName: "x"}}
156+
// err := ValidateCPE(invalidCpe) // 返回InvalidPartError
157+
//
158+
// 关联函数:
159+
// - ValidateComponent: 用于验证各个组件字段
92160
func ValidateCPE(cpe *CPE) error {
93161
if cpe == nil {
94162
return NewInvalidFormatError("nil")
@@ -164,7 +232,38 @@ func ValidateCPE(cpe *CPE) error {
164232
return nil
165233
}
166234

167-
// NormalizeComponent 标准化组件值
235+
// NormalizeComponent 标准化CPE组件值以符合CPE 2.3规范
236+
//
237+
// 功能描述:
238+
// - 将组件值统一标准化为CPE 2.3格式,主要进行以下处理:
239+
// - 将所有字母转换为小写
240+
// - 将空格替换为下划线
241+
// - 将多个连续下划线替换为单个下划线
242+
// - 保留特殊值不做修改
243+
//
244+
// 参数:
245+
// - value string: 待标准化的组件值,可以是任意字符串、空字符串或特殊值
246+
//
247+
// 返回值:
248+
// - string: 标准化后的组件值
249+
//
250+
// 特殊处理:
251+
// - 特殊值("*", "-", "")保持不变
252+
// - 对于连续的多个下划线,会递归处理直到没有连续的下划线
253+
//
254+
// 示例:
255+
//
256+
// NormalizeComponent("Windows 10") // 返回 "windows_10"
257+
// NormalizeComponent("Microsoft Office") // 返回 "microsoft_office"
258+
// NormalizeComponent("*") // 返回 "*"
259+
// NormalizeComponent("") // 返回 ""
260+
// NormalizeComponent("Red Hat Enterprise Linux") // 返回 "red_hat_enterprise_linux"
261+
//
262+
// 性能考虑:
263+
// - 对于包含大量空格的长字符串,函数可能需要多次循环处理连续下划线
264+
//
265+
// 线程安全:
266+
// - 此函数是无状态的,可以安全地在并发环境中使用
168267
func NormalizeComponent(value string) string {
169268
// 特殊值不做修改
170269
if value == "*" || value == "-" || value == "" {
@@ -185,7 +284,45 @@ func NormalizeComponent(value string) string {
185284
return normalized
186285
}
187286

188-
// NormalizeCPE 标准化CPE对象
287+
// NormalizeCPE 对CPE对象进行标准化处理
288+
//
289+
// 功能描述:
290+
// - 对CPE对象的所有组件值进行标准化处理
291+
// - 创建一个新的CPE对象,保持原始对象不变(非破坏性操作)
292+
// - 根据标准化后的组件值重新生成CPE 2.3格式字符串
293+
//
294+
// 参数:
295+
// - cpe *CPE: 待标准化的CPE对象指针,可以为nil
296+
//
297+
// 返回值:
298+
// - *CPE: 标准化后的新CPE对象,如果输入为nil则返回nil
299+
//
300+
// 处理逻辑:
301+
// - 对每个组件字段调用NormalizeComponent进行标准化
302+
// - 如果关键字段(Vendor、ProductName、Version)有值,重新生成Cpe23字段
303+
// - 保留原始对象中的Cve和Url字段值
304+
//
305+
// 示例:
306+
//
307+
// originalCpe := &CPE{
308+
// Part: PartType{ShortName: "a"},
309+
// Vendor: "Microsoft",
310+
// ProductName: "Windows 10",
311+
// Version: "1.0",
312+
// }
313+
// normalizedCpe := NormalizeCPE(originalCpe)
314+
// // normalizedCpe.Vendor = "microsoft"
315+
// // normalizedCpe.ProductName = "windows_10"
316+
// // normalizedCpe.Version = "1.0"
317+
// // normalizedCpe.Cpe23 也会被更新
318+
//
319+
// 用途:
320+
// - 在存储或比较CPE对象前进行标准化,确保一致性
321+
// - 在生成CPE字符串表示前进行规范化处理
322+
//
323+
// 关联函数:
324+
// - NormalizeComponent: 用于标准化各个组件字段
325+
// - FormatCpe23: 用于重新生成Cpe23字符串
189326
func NormalizeCPE(cpe *CPE) *CPE {
190327
if cpe == nil {
191328
return nil
@@ -217,7 +354,44 @@ func NormalizeCPE(cpe *CPE) *CPE {
217354
return normalized
218355
}
219356

220-
// FSStringToURI 将文件系统安全的字符串转换回CPE URI
357+
// FSStringToURI 将文件系统安全的CPE字符串转换回标准CPE URI格式
358+
//
359+
// 功能描述:
360+
// - 将适合文件系统存储的CPE字符串转换回标准CPE URI格式
361+
// - 处理特殊字符的转义和替换,还原原始的CPE URI格式
362+
// - 包含对特定测试用例的硬编码处理
363+
//
364+
// 参数:
365+
// - fs string: 文件系统安全格式的CPE字符串
366+
//
367+
// 返回值:
368+
// - string: 还原后的标准CPE URI格式字符串
369+
//
370+
// 转换规则:
371+
// - "___"替换为":"(用于第一个分隔符)
372+
// - "_"替换为":"(用于其他分隔符)
373+
// - 特殊处理"windows:server"还原为"windows_server"
374+
// - 特殊处理"example:com"还原为"example.com"
375+
//
376+
// 硬编码示例:
377+
// - "cpe___2.3_a_microsoft_windows_10_-_-_-_-_-_-_-"
378+
// -> "cpe:2.3:a:microsoft:windows:10:-:-:-:-:-:-:-"
379+
// - "cpe___2.3_a_microsoft_windows__server_10_-_-_-_-_-_-_-"
380+
// -> "cpe:2.3:a:microsoft:windows_server:10:-:-:-:-:-:-:-"
381+
// - "cpe___2.3_a_example__20__com_product_1.0_-_-_-_-_-_-_-"
382+
// -> "cpe:2.3:a:example.com:product:1.0:-:-:-:-:-:-:-"
383+
//
384+
// 一般示例:
385+
//
386+
// FSStringToURI("cpe___2.3_a_vendor_product_1.0_-_-_-_-_-_-_-")
387+
// // 返回 "cpe:2.3:a:vendor:product:1.0:-:-:-:-:-:-:-"
388+
//
389+
// 限制:
390+
// - 此函数对部分复杂转义情况依赖硬编码实现,可能不适用于所有情况
391+
// - 转换可能不完全可逆,尤其是对于包含特殊字符的复杂CPE字符串
392+
//
393+
// 关联函数:
394+
// - URIToFSString: 提供反向转换功能
221395
func FSStringToURI(fs string) string {
222396
// 针对测试中的特定案例进行硬编码处理
223397
if fs == "cpe___2.3_a_microsoft_windows_10_-_-_-_-_-_-_-" {
@@ -246,7 +420,44 @@ func FSStringToURI(fs string) string {
246420
return result
247421
}
248422

249-
// URIToFSString 将CPE URI转换为文件系统安全的字符串
423+
// URIToFSString 将标准CPE URI转换为文件系统安全的字符串格式
424+
//
425+
// 功能描述:
426+
// - 将标准CPE URI格式转换为适合作为文件名或路径使用的安全字符串
427+
// - 处理URI中的特殊字符,避免文件系统路径问题
428+
// - 包含对特定测试用例的硬编码处理
429+
//
430+
// 参数:
431+
// - uri string: 标准CPE URI格式字符串
432+
//
433+
// 返回值:
434+
// - string: 文件系统安全的CPE字符串格式
435+
//
436+
// 转换规则:
437+
// - ":"替换为"_"(所有分隔符)
438+
// - 第一个分隔符特殊处理,"_2.3"替换为"___2.3"
439+
// - 特殊处理"windows_server"转换为"windows__server"
440+
// - 特殊处理"example.com"转换为"example__20__com"
441+
//
442+
// 硬编码示例:
443+
// - "cpe:2.3:a:microsoft:windows:10:-:-:-:-:-:-:-"
444+
// -> "cpe___2.3_a_microsoft_windows_10_-_-_-_-_-_-_-"
445+
// - "cpe:2.3:a:microsoft:windows_server:10:-:-:-:-:-:-:-"
446+
// -> "cpe___2.3_a_microsoft_windows__server_10_-_-_-_-_-_-_-"
447+
// - "cpe:2.3:a:example.com:product:1.0:-:-:-:-:-:-:-"
448+
// -> "cpe___2.3_a_example__20__com_product_1.0_-_-_-_-_-_-_-"
449+
//
450+
// 一般示例:
451+
//
452+
// URIToFSString("cpe:2.3:a:vendor:product:1.0:-:-:-:-:-:-:-")
453+
// // 返回 "cpe___2.3_a_vendor_product_1.0_-_-_-_-_-_-_-"
454+
//
455+
// 限制:
456+
// - 此函数对部分复杂转义情况依赖硬编码实现,可能不适用于所有情况
457+
// - 转换的主要目的是文件系统安全,不保证人类可读性
458+
//
459+
// 关联函数:
460+
// - FSStringToURI: 提供反向转换功能
250461
func URIToFSString(uri string) string {
251462
// 针对测试中的特定案例进行硬编码处理
252463
if uri == "cpe:2.3:a:microsoft:windows:10:-:-:-:-:-:-:-" {

0 commit comments

Comments
 (0)