字符串长度混淆¶
ID: swift/string-length-conflation
Kind: path-problem
Security severity: 7.8
Severity: error
Precision: high
Tags:
- security
- external/cwe/cwe-135
Query suites:
- swift-code-scanning.qls
- swift-security-extended.qls
- swift-security-and-quality.qls
在 NSString
中使用 String
的长度值,或在 NSString
中使用 String
的计数,可能会导致意外行为,包括(在某些情况下)缓冲区溢出。这是因为某些 Unicode 序列在 String
中表示为一个字符,但在 NSString
中表示为多个字符的序列。例如,带有肤色修饰符的“竖起大拇指”表情符号(👍🏿)表示为 U+1F44D (👍),然后是修饰符 U+1F3FF。
此问题也可能出现在不适当的地方使用 String.utf8.count
、String.utf16.count
或 String.unicodeScalars.count
的值时。
建议¶
使用 String.count
处理 String
。使用 NSString.length
处理 NSString
。不要将两种类型的长度和偏移量值混合使用,因为它们不是兼容的度量。
如果您需要在 Range
和 NSRange
之间进行转换,请直接使用相应的初始化器。不要尝试使用不兼容的长度和偏移量值来完成转换。
示例¶
在以下示例中,将 String
转换为 NSString
,但范围是从 String
创建的,以便对其进行一些处理。
func myFunction(s: String) {
let ns = NSString(string: s)
let nsrange = NSMakeRange(0, s.count) // BAD: String length used in NSMakeRange
// ... use nsrange to process ns
}
这很危险,因为如果输入包含某些字符,则在 String
上计算的范围对于 NSString
来说将是错误的。这会导致后续字符串处理中的行为不正确。为了解决这个问题,我们可以使用 NSString.length
来创建 NSRange
,如下所示
func myFunction(s: String) {
let ns = NSString(string: s)
let nsrange = NSMakeRange(0, ns.length) // Fixed: NSString length used in NSMakeRange
// ... use nsrange to process ns
}
参考资料¶
常见弱点枚举:CWE-135.