CodeQL 文档

长度比较偏差一位

ID: go/index-out-of-bounds
Kind: problem
Security severity: 
Severity: error
Precision: high
Tags:
   - reliability
   - correctness
   - logic
   - external/cwe/cwe-193
Query suites:
   - go-security-and-quality.qls

点击查看 CodeQL 代码库中的查询

数组、切片或字符串上的索引操作使用的索引应最多比长度小 1。如果检查要访问的索引是否小于或等于长度 (<=),而不是小于长度 (<),则索引可能会超出界限。

建议

在将潜在索引与长度进行比较时,使用小于 (<) 而不是小于或等于 (<=)。对于迭代每个元素的 for 循环,更好的解决方案是使用 range 循环,而不是循环访问显式索引。

示例

以下示例展示了一个方法,该方法检查某个值是否出现在以逗号分隔的值列表中

package main

import "strings"

func containsBad(searchName string, names string) bool {
	values := strings.Split(names, ",")
	// BAD: index could be equal to length
	for i := 0; i <= len(values); i++ {
		// When i = length, this access will be out of bounds
		if values[i] == searchName {
			return true
		}
	}
	return false
}

使用索引变量 i 的循环用于迭代以逗号分隔的列表中的元素。但是,循环的终止条件被错误地指定为 i <= len(values)。当 i 等于 len(values) 时,此条件成立,但在这种情况下,循环体中的访问权限 values[i] 将超出界限。

一种可能的解决方案是用 i < len(values) 替换 i <= len(values)。更好的解决方案是使用 range 循环,这样就无需显式操作索引变量

package main

import "strings"

func containsGood(searchName string, names string) bool {
	values := strings.Split(names, ",")
	// GOOD: Avoid using indexes, use range loop instead
	for _, name := range values {
		if name == searchName {
			return true
		}
	}
	return true
}

参考

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