CodeQL 文档

字符串长度混淆

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

点击查看 CodeQL 仓库中的查询

NSString 中使用 String 的长度值,或在 NSString 中使用 String 的计数,可能会导致意外行为,包括(在某些情况下)缓冲区溢出。这是因为某些 Unicode 序列在 String 中表示为一个字符,但在 NSString 中表示为多个字符的序列。例如,带有肤色修饰符的“竖起大拇指”表情符号(👍🏿)表示为 U+1F44D (👍),然后是修饰符 U+1F3FF。

此问题也可能出现在不适当的地方使用 String.utf8.countString.utf16.countString.unicodeScalars.count 的值时。

建议

使用 String.count 处理 String。使用 NSString.length 处理 NSString。不要将两种类型的长度和偏移量值混合使用,因为它们不是兼容的度量。

如果您需要在 RangeNSRange 之间进行转换,请直接使用相应的初始化器。不要尝试使用不兼容的长度和偏移量值来完成转换。

示例

在以下示例中,将 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
}

参考资料

  • ©GitHub, Inc.
  • 条款
  • 隐私