引自ngx_hash.c:
ngx_strlow(elt->name, names[n].key.data, names[n].key.len);
将小写字符串复制到elt->name
。
此处elt
的类型为ngx_hash_elt_t *
:
typedef struct {
void *value;
u_short len;
u_char name[1];
} ngx_hash_elt_t;
如您所见name
只有1
字符宽,IMO ngx_strlow
会导致缓冲区溢出,但它实际上没有问题,有人可以解释吗?
答案 0 :(得分:2)
通常定义这种结构,以便程序员(如果她想要len = 100)可以去:
ngx_hash_elt_t *X;
X = malloc(sizeof(ng_has_elt_t)+99);
在这种情况下,用户和库引用X.name仍然有效且有意义,因为它是指向字符串开头的指针。
答案 1 :(得分:1)
可能是使用malloc()在堆上分配结构。
它可以像这样工作:
size_t decent_length = <something big enough to hold a string>;
ngx_hash_elt_t *elt = malloc (sizeof (*p) + decent_length);
答案 2 :(得分:0)
这是用C创建可变长度缓冲区的技巧。使最后一个元素长1个字节,并分配更多。对于此结构,可以像下面那样分配ngx_hash_elt_t
,例如:
ngx_hash_elt_t* alloc_hash_elt(int name_len)
{
return malloc(sizeof(ngx_hash_elt_t) - 1 + name_len);
}
name
元素现在可以安全地使用您分配的额外空间。
答案 3 :(得分:0)
如果elt被分配为
elt = (ngx_hash_elt_t*)malloc(sizeof(ngx_hash_elt_t));
,然后它将导致字符串长于1的溢出。但是,很可能,它被分配为:
elt = (ngx_hash_elt_t*)malloc(sizeof(ngx_hash_elt_t) + maximum_possible_length);
,所以没有溢出。