Ubuntu 下 nginx-1.24.0 源码分析 - ngx_atoi 函数
ngx_atoi
声明在 src/core/ngx_string.h
ngx_int_t ngx_atoi(u_char *line, size_t n);
定义在 src/core/ngx_string.c
ngx_int_t ngx_atoi(u_char *line, size_t n) { ngx_int_t value, cutoff, cutlim; if (n == 0) { return NGX_ERROR; } cutoff = NGX_MAX_INT_T_VALUE / 10; cutlim = NGX_MAX_INT_T_VALUE % 10; for (value = 0; n--; line++) { if (*line < '0' || *line > '9') { return NGX_ERROR; } if (value >= cutoff && (value > cutoff || *line - '0' > cutlim)) { return NGX_ERROR; } value = value * 10 + (*line - '0'); } return value; }
函数签名
ngx_int_t ngx_atoi(u_char *line, size_t n)
u_char *line
:待转换的字符串指针size_t n
:字符串有效长度(避免依赖'\0'终止符)返回值 :
- 如果成功,返回转换后的整数值。
- 如果失败(例如字符串包含非数字字符或超出整数范围),返回
NGX_ERROR
。功能
该函数的作用是将一个长度为
n
的字符串转换为一个整数,并确保转换过程中不会发生溢出。
1. 参数检查
if (n == 0) { return NGX_ERROR; }
检查输入字符串的长度是否为 0。
如果长度为 0,则无法进行任何转换,直接返回错误。
这是最基本的边界条件检查,防止后续逻辑因无效输入而崩溃。
2. 定义变量并计算溢出阈值
ngx_int_t value, cutoff, cutlim; cutoff = NGX_MAX_INT_T_VALUE / 10; cutlim = NGX_MAX_INT_T_VALUE % 10;
变量说明 :
value
:用于存储当前累积的整数值。
cutoff
:整数最大值除以 10 的结果。
cutlim
:整数最大值对 10 取余的结果。
NGX_MAX_INT_T_VALUE
:当前平台的整型最大值定义在 src/core/ngx_config.h
#define NGX_MAX_INT_T_VALUE 9223372036854775807
在每次累加之前,通过比较当前值与
cutoff
和cutlim
来判断是否会溢出。这种方法避免了直接进行溢出操作导致未定义行为。
遍历字符串并逐字符处理
for (value = 0; n--; line++) { if (*line < '0' || *line > '9') { return NGX_ERROR; }
作用 :逐字符遍历输入字符串,并检查每个字符是否为合法的数字字符。
逻辑 :
*line < '0' || *line > '9'
:判断当前字符是否不在'0'
到'9'
范围内。如果发现非法字符,立即返回错误。
意图 :
确保输入字符串只包含数字字符。
提前终止无效输入的处理,提高效率。
检测整数溢出
if (value >= cutoff && (value > cutoff || *line - '0' > cutlim)) { return NGX_ERROR; }
作用 :在累加之前,检测当前值是否会超出整数范围。
逻辑 :
value >= cutoff
:当前值已经接近整数最大值。
(value > cutoff || *line - '0' > cutlim)
:如果当前值大于
cutoff
,则一定会溢出。如果当前值等于
cutoff
,但当前字符对应的数字大于cutlim
,也会溢出。意图 :
通过提前检测溢出,避免在累加时触发未定义行为。
这是 Nginx 设计中非常重要的健壮性保障。
累加当前字符的数值
value = value * 10 + (*line - '0');
- 作用 :将当前字符的数值累加到
value
中。- 逻辑 :
*line - '0'
:将字符'0'
到'9'
转换为对应的整数值 0 到 9。value * 10
:将当前值左移一位(相当于乘以 10)。- 最终结果是将当前字符的数值追加到已有整数的末尾。
- 意图 :
- 实现字符串到整数的逐步转换。
返回最终结果
return value;
当所有字符都成功处理后,返回最终的整数值