6
6
"strings"
7
7
)
8
8
9
+ // CPE包实现了通用平台枚举(Common Platform Enumeration)标准的解析、验证和格式化功能。
10
+ // 本包支持CPE 2.3规范,提供了CPE字符串的解析、验证、标准化以及不同格式间的转换功能。
11
+
9
12
// CPE 2.3规范中定义的字符集和限制
10
13
var (
11
14
// 有效URI字符集
59
62
// Set of illegal characters in CPE components
60
63
var illegalChars = []rune {'!' , '@' , '#' , '$' , '%' , '^' , '&' , '(' , ')' , '{' , '}' , '[' , ']' , '|' , '\\' , ';' , '"' , '\'' , '<' , '>' , '?' }
61
64
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
+ // - 此函数不验证值的语义正确性,只验证字符的合法性
63
92
func ValidateComponent (value string , componentName string ) error {
64
93
// 空字符串被视为通配符
65
94
if value == "" {
@@ -88,7 +117,46 @@ func ValidateComponent(value string, componentName string) error {
88
117
return nil
89
118
}
90
119
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: 用于验证各个组件字段
92
160
func ValidateCPE (cpe * CPE ) error {
93
161
if cpe == nil {
94
162
return NewInvalidFormatError ("nil" )
@@ -164,7 +232,38 @@ func ValidateCPE(cpe *CPE) error {
164
232
return nil
165
233
}
166
234
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
+ // - 此函数是无状态的,可以安全地在并发环境中使用
168
267
func NormalizeComponent (value string ) string {
169
268
// 特殊值不做修改
170
269
if value == "*" || value == "-" || value == "" {
@@ -185,7 +284,45 @@ func NormalizeComponent(value string) string {
185
284
return normalized
186
285
}
187
286
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字符串
189
326
func NormalizeCPE (cpe * CPE ) * CPE {
190
327
if cpe == nil {
191
328
return nil
@@ -217,7 +354,44 @@ func NormalizeCPE(cpe *CPE) *CPE {
217
354
return normalized
218
355
}
219
356
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: 提供反向转换功能
221
395
func FSStringToURI (fs string ) string {
222
396
// 针对测试中的特定案例进行硬编码处理
223
397
if fs == "cpe___2.3_a_microsoft_windows_10_-_-_-_-_-_-_-" {
@@ -246,7 +420,44 @@ func FSStringToURI(fs string) string {
246
420
return result
247
421
}
248
422
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: 提供反向转换功能
250
461
func URIToFSString (uri string ) string {
251
462
// 针对测试中的特定案例进行硬编码处理
252
463
if uri == "cpe:2.3:a:microsoft:windows:10:-:-:-:-:-:-:-" {
0 commit comments