为什么nginx中的这段代码不会导致缓冲区溢出?

时间:2011-06-22 12:45:25

标签: c nginx

引自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会导致缓冲区溢出,但它实际上没有问题,有人可以解释吗?

4 个答案:

答案 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);

,所以没有溢出。