src/http/modules/ngx_http_gzip_filter_module.c:1010: error: Buffer Overrun L3
  Offset added: [-4, +oo] (⇐ [0, 2] + [-4, +oo]) Size: [0, +oo] by call to `ngx_http_add_variable`.

src/http/modules/ngx_http_gzip_filter_module.c:1010:11: Call
1008.     ngx_http_variable_t  *var;
1009. 
1010.     var = ngx_http_add_variable(cf, &ngx_http_gzip_ratio, NGX_HTTP_VAR_NOHASH);
                ^
1011.     if (var == NULL) {
1012.         return NGX_ERROR;

src/http/ngx_http_variables.c:257:1: Parameter `name->len`
  255. 
  256. 
  257. ngx_http_variable_t *
       ^
  258. ngx_http_add_variable(ngx_conf_t *cf, ngx_str_t *name, ngx_uint_t flags)
  259. {

src/http/ngx_http_variables.c:292:5: Assignment
  290.     }
  291. 
  292.     v->name.len = name->len;
           ^
  293.     v->name.data = ngx_pnalloc(cf->pool, name->len);
  294.     if (v->name.data == NULL) {

src/http/ngx_http_variables.c:306:10: Call
  304.     v->index = 0;
  305. 
  306.     rc = ngx_hash_add_key(cmcf->variables_keys, &v->name, v, 0);
                ^
  307. 
  308.     if (rc == NGX_ERROR) {

src/core/ngx_hash.c:749:13: <Offset trace>
747. 
748.         if (key->len > 1 && key->data[0] == '.') {
749.             skip = 1;
                 ^
750.             goto wildcard;
751.         }

src/core/ngx_hash.c:749:13: Assignment
    747. 
    748.         if (key->len > 1 && key->data[0] == '.') {
    749.             skip = 1;
                     ^
    750.             goto wildcard;
    751.         }

src/core/ngx_hash.c:974:5: Assignment
    972.     }
    973. 
    974.     name->len = last - skip;
             ^
    975.     name->data = ngx_pnalloc(ha->temp_pool, name->len);
    976.     if (name->data == NULL) {

src/core/ngx_hash.c:713:1: <Length trace>
711. 
712. 
713. ngx_int_t
     ^
714. ngx_hash_add_key(ngx_hash_keys_arrays_t *ha, ngx_str_t *key, void *value,
715.     ngx_uint_t flags)

src/core/ngx_hash.c:713:1: Parameter `*key->data`
    711. 
    712. 
    713. ngx_int_t
         ^
    714. ngx_hash_add_key(ngx_hash_keys_arrays_t *ha, ngx_str_t *key, void *value,
    715.     ngx_uint_t flags)

src/core/ngx_hash.c:980:5: Array access: Offset added: [-4, +oo] (⇐ [0, 2] + [-4, +oo]) Size: [0, +oo] by call to `ngx_http_add_variable` 
    978.     }
    979. 
    980.     ngx_memcpy(name->data, key->data + skip, name->len);
             ^
    981. 
    982.     return NGX_OK;

ngx_int_t
ngx_hash_add_key(ngx_hash_keys_arrays_t *ha, ngx_str_t *key, void *value,
    ngx_uint_t flags)
{
    size_t           len;
    u_char          *p;
    ngx_str_t       *name;
    ngx_uint_t       i, k, n, skip, last;
    ngx_array_t     *keys, *hwc;
    ngx_hash_key_t  *hk;
    last = key->len;
    if (flags & NGX_HASH_WILDCARD_KEY) {
        n = 0;
        for (i = 0; i < key->len; i++) {
            if (key->data[i] == '*') {
                if (++n > 1) {
                    return NGX_DECLINED;
                }
            }
            if (key->data[i] == '.' && key->data[i + 1] == '.') {
                return NGX_DECLINED;
            }
        }
        if (key->len > 1 && key->data[0] == '.') {
            skip = 1;
            goto wildcard;
        }
        if (key->len > 2) {
            if (key->data[0] == '*' && key->data[1] == '.') {
                skip = 2;
                goto wildcard;
            }
            if (key->data[i - 2] == '.' && key->data[i - 1] == '*') {
                skip = 0;
                last -= 2;
                goto wildcard;
            }
        }
        if (n) {
            return NGX_DECLINED;
        }
    }
    k = 0;
    for (i = 0; i < last; i++) {
        if (!(flags & NGX_HASH_READONLY_KEY)) {
            key->data[i] = ngx_tolower(key->data[i]);
        }
        k = ngx_hash(k, key->data[i]);
    }
    k %= ha->hsize;
    name = ha->keys_hash[k].elts;
    if (name) {
        for (i = 0; i < ha->keys_hash[k].nelts; i++) {
            if (last != name[i].len) {
                continue;
            }
            if (ngx_strncmp(key->data, name[i].data, last) == 0) {
                return NGX_BUSY;
            }
        }
    } else {
        if (ngx_array_init(&ha->keys_hash[k], ha->temp_pool, 4,
                           sizeof(ngx_str_t))
            != NGX_OK)
        {
            return NGX_ERROR;
        }
    }
    name = ngx_array_push(&ha->keys_hash[k]);
    if (name == NULL) {
        return NGX_ERROR;
    }
    *name = *key;
    hk = ngx_array_push(&ha->keys);
    if (hk == NULL) {
        return NGX_ERROR;
    }
    hk->key = *key;
    hk->key_hash = ngx_hash_key(key->data, last);
    hk->value = value;
    return NGX_OK;
wildcard:
    k = ngx_hash_strlow(&key->data[skip], &key->data[skip], last - skip);
    k %= ha->hsize;
    if (skip == 1) {
        name = ha->keys_hash[k].elts;
        if (name) {
            len = last - skip;
            for (i = 0; i < ha->keys_hash[k].nelts; i++) {
                if (len != name[i].len) {
                    continue;
                }
                if (ngx_strncmp(&key->data[1], name[i].data, len) == 0) {
                    return NGX_BUSY;
                }
            }
        } else {
            if (ngx_array_init(&ha->keys_hash[k], ha->temp_pool, 4,
                               sizeof(ngx_str_t))
                != NGX_OK)
            {
                return NGX_ERROR;
            }
        }
        name = ngx_array_push(&ha->keys_hash[k]);
        if (name == NULL) {
            return NGX_ERROR;
        }
        name->len = last - 1;
        name->data = ngx_pnalloc(ha->temp_pool, name->len);
        if (name->data == NULL) {
            return NGX_ERROR;
        }
        ngx_memcpy(name->data, &key->data[1], name->len);
    }
    if (skip) {
        p = ngx_pnalloc(ha->temp_pool, last);
        if (p == NULL) {
            return NGX_ERROR;
        }
        len = 0;
        n = 0;
        for (i = last - 1; i; i--) {
            if (key->data[i] == '.') {
                ngx_memcpy(&p[n], &key->data[i + 1], len);
                n += len;
                p[n++] = '.';
                len = 0;
                continue;
            }
            len++;
        }
        if (len) {
            ngx_memcpy(&p[n], &key->data[1], len);
            n += len;
        }
        p[n] = '\0';
        hwc = &ha->dns_wc_head;
        keys = &ha->dns_wc_head_hash[k];
    } else {
        last++;
        p = ngx_pnalloc(ha->temp_pool, last);
        if (p == NULL) {
            return NGX_ERROR;
        }
        ngx_cpystrn(p, key->data, last);
        hwc = &ha->dns_wc_tail;
        keys = &ha->dns_wc_tail_hash[k];
    }
    hk = ngx_array_push(hwc);
    if (hk == NULL) {
        return NGX_ERROR;
    }
    hk->key.len = last - 1;
    hk->key.data = p;
    hk->key_hash = 0;
    hk->value = value;
    name = keys->elts;
    if (name) {
        len = last - skip;
        for (i = 0; i < keys->nelts; i++) {
            if (len != name[i].len) {
                continue;
            }
            if (ngx_strncmp(key->data + skip, name[i].data, len) == 0) {
                return NGX_BUSY;
            }
        }
    } else {
        if (ngx_array_init(keys, ha->temp_pool, 4, sizeof(ngx_str_t)) != NGX_OK)
        {
            return NGX_ERROR;
        }
    }
    name = ngx_array_push(keys);
    if (name == NULL) {
        return NGX_ERROR;
    }
    name->len = last - skip;
    name->data = ngx_pnalloc(ha->temp_pool, name->len);
    if (name->data == NULL) {
        return NGX_ERROR;
    }
    ngx_memcpy(name->data, key->data + skip, name->len);
    return NGX_OK;
}
['static ngx_int_t\nngx_http_gzip_add_variables(ngx_conf_t *cf)\n{\n    ngx_http_variable_t  *var;\n    var = ngx_http_add_variable(cf, &ngx_http_gzip_ratio, NGX_HTTP_VAR_NOHASH);\n    if (var == NULL) {\n        return NGX_ERROR;\n    }\n    var->get_handler = ngx_http_gzip_ratio_variable;\n    return NGX_OK;\n}', 'ngx_http_variable_t *\nngx_http_add_variable(ngx_conf_t *cf, ngx_str_t *name, ngx_uint_t flags)\n{\n    ngx_int_t                   rc;\n    ngx_uint_t                  i;\n    ngx_hash_key_t             *key;\n    ngx_http_variable_t        *v;\n    ngx_http_core_main_conf_t  *cmcf;\n    cmcf = ngx_http_conf_get_module_main_conf(cf, ngx_http_core_module);\n    key = cmcf->variables_keys->keys.elts;\n    for (i = 0; i < cmcf->variables_keys->keys.nelts; i++) {\n        if (name->len != key[i].key.len\n            || ngx_strncasecmp(name->data, key[i].key.data, name->len) != 0)\n        {\n            continue;\n        }\n        v = key[i].value;\n        if (!(v->flags & NGX_HTTP_VAR_CHANGEABLE)) {\n            ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,\n                               "the duplicate \\"%V\\" variable", name);\n            return NULL;\n        }\n        return v;\n    }\n    v = ngx_palloc(cf->pool, sizeof(ngx_http_variable_t));\n    if (v == NULL) {\n        return NULL;\n    }\n    v->name.len = name->len;\n    v->name.data = ngx_pnalloc(cf->pool, name->len);\n    if (v->name.data == NULL) {\n        return NULL;\n    }\n    ngx_strlow(v->name.data, name->data, name->len);\n    v->set_handler = NULL;\n    v->get_handler = NULL;\n    v->data = 0;\n    v->flags = flags;\n    v->index = 0;\n    rc = ngx_hash_add_key(cmcf->variables_keys, &v->name, v, 0);\n    if (rc == NGX_ERROR) {\n        return NULL;\n    }\n    if (rc == NGX_BUSY) {\n        ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,\n                           "conflicting variable name \\"%V\\"", name);\n        return NULL;\n    }\n    return v;\n}', "ngx_int_t\nngx_hash_add_key(ngx_hash_keys_arrays_t *ha, ngx_str_t *key, void *value,\n    ngx_uint_t flags)\n{\n    size_t           len;\n    u_char          *p;\n    ngx_str_t       *name;\n    ngx_uint_t       i, k, n, skip, last;\n    ngx_array_t     *keys, *hwc;\n    ngx_hash_key_t  *hk;\n    last = key->len;\n    if (flags & NGX_HASH_WILDCARD_KEY) {\n        n = 0;\n        for (i = 0; i < key->len; i++) {\n            if (key->data[i] == '*') {\n                if (++n > 1) {\n                    return NGX_DECLINED;\n                }\n            }\n            if (key->data[i] == '.' && key->data[i + 1] == '.') {\n                return NGX_DECLINED;\n            }\n        }\n        if (key->len > 1 && key->data[0] == '.') {\n            skip = 1;\n            goto wildcard;\n        }\n        if (key->len > 2) {\n            if (key->data[0] == '*' && key->data[1] == '.') {\n                skip = 2;\n                goto wildcard;\n            }\n            if (key->data[i - 2] == '.' && key->data[i - 1] == '*') {\n                skip = 0;\n                last -= 2;\n                goto wildcard;\n            }\n        }\n        if (n) {\n            return NGX_DECLINED;\n        }\n    }\n    k = 0;\n    for (i = 0; i < last; i++) {\n        if (!(flags & NGX_HASH_READONLY_KEY)) {\n            key->data[i] = ngx_tolower(key->data[i]);\n        }\n        k = ngx_hash(k, key->data[i]);\n    }\n    k %= ha->hsize;\n    name = ha->keys_hash[k].elts;\n    if (name) {\n        for (i = 0; i < ha->keys_hash[k].nelts; i++) {\n            if (last != name[i].len) {\n                continue;\n            }\n            if (ngx_strncmp(key->data, name[i].data, last) == 0) {\n                return NGX_BUSY;\n            }\n        }\n    } else {\n        if (ngx_array_init(&ha->keys_hash[k], ha->temp_pool, 4,\n                           sizeof(ngx_str_t))\n            != NGX_OK)\n        {\n            return NGX_ERROR;\n        }\n    }\n    name = ngx_array_push(&ha->keys_hash[k]);\n    if (name == NULL) {\n        return NGX_ERROR;\n    }\n    *name = *key;\n    hk = ngx_array_push(&ha->keys);\n    if (hk == NULL) {\n        return NGX_ERROR;\n    }\n    hk->key = *key;\n    hk->key_hash = ngx_hash_key(key->data, last);\n    hk->value = value;\n    return NGX_OK;\nwildcard:\n    k = ngx_hash_strlow(&key->data[skip], &key->data[skip], last - skip);\n    k %= ha->hsize;\n    if (skip == 1) {\n        name = ha->keys_hash[k].elts;\n        if (name) {\n            len = last - skip;\n            for (i = 0; i < ha->keys_hash[k].nelts; i++) {\n                if (len != name[i].len) {\n                    continue;\n                }\n                if (ngx_strncmp(&key->data[1], name[i].data, len) == 0) {\n                    return NGX_BUSY;\n                }\n            }\n        } else {\n            if (ngx_array_init(&ha->keys_hash[k], ha->temp_pool, 4,\n                               sizeof(ngx_str_t))\n                != NGX_OK)\n            {\n                return NGX_ERROR;\n            }\n        }\n        name = ngx_array_push(&ha->keys_hash[k]);\n        if (name == NULL) {\n            return NGX_ERROR;\n        }\n        name->len = last - 1;\n        name->data = ngx_pnalloc(ha->temp_pool, name->len);\n        if (name->data == NULL) {\n            return NGX_ERROR;\n        }\n        ngx_memcpy(name->data, &key->data[1], name->len);\n    }\n    if (skip) {\n        p = ngx_pnalloc(ha->temp_pool, last);\n        if (p == NULL) {\n            return NGX_ERROR;\n        }\n        len = 0;\n        n = 0;\n        for (i = last - 1; i; i--) {\n            if (key->data[i] == '.') {\n                ngx_memcpy(&p[n], &key->data[i + 1], len);\n                n += len;\n                p[n++] = '.';\n                len = 0;\n                continue;\n            }\n            len++;\n        }\n        if (len) {\n            ngx_memcpy(&p[n], &key->data[1], len);\n            n += len;\n        }\n        p[n] = '\\0';\n        hwc = &ha->dns_wc_head;\n        keys = &ha->dns_wc_head_hash[k];\n    } else {\n        last++;\n        p = ngx_pnalloc(ha->temp_pool, last);\n        if (p == NULL) {\n            return NGX_ERROR;\n        }\n        ngx_cpystrn(p, key->data, last);\n        hwc = &ha->dns_wc_tail;\n        keys = &ha->dns_wc_tail_hash[k];\n    }\n    hk = ngx_array_push(hwc);\n    if (hk == NULL) {\n        return NGX_ERROR;\n    }\n    hk->key.len = last - 1;\n    hk->key.data = p;\n    hk->key_hash = 0;\n    hk->value = value;\n    name = keys->elts;\n    if (name) {\n        len = last - skip;\n        for (i = 0; i < keys->nelts; i++) {\n            if (len != name[i].len) {\n                continue;\n            }\n            if (ngx_strncmp(key->data + skip, name[i].data, len) == 0) {\n                return NGX_BUSY;\n            }\n        }\n    } else {\n        if (ngx_array_init(keys, ha->temp_pool, 4, sizeof(ngx_str_t)) != NGX_OK)\n        {\n            return NGX_ERROR;\n        }\n    }\n    name = ngx_array_push(keys);\n    if (name == NULL) {\n        return NGX_ERROR;\n    }\n    name->len = last - skip;\n    name->data = ngx_pnalloc(ha->temp_pool, name->len);\n    if (name->data == NULL) {\n        return NGX_ERROR;\n    }\n    ngx_memcpy(name->data, key->data + skip, name->len);\n    return NGX_OK;\n}"]