src/http/modules/ngx_http_fastcgi_module.c:3069: error: Buffer Overrun L3
  Offset: [0, 535] (⇐ [0, 24] + [0, 511]) Size: [0, 4120] by call to `ngx_http_upstream_hide_headers_hash`.

src/http/modules/ngx_http_fastcgi_module.c:3065:5: Assignment
3063.     ngx_conf_merge_str_value(conf->index, prev->index, "");
3064. 
3065.     hash.max_size = 512;
          ^
3066.     hash.bucket_size = ngx_align(64, ngx_cacheline_size);
3067.     hash.name = "fastcgi_hide_headers_hash";

src/http/modules/ngx_http_fastcgi_module.c:3069:9: Call
3067.     hash.name = "fastcgi_hide_headers_hash";
3068. 
3069.     if (ngx_http_upstream_hide_headers_hash(cf, &conf->upstream,
              ^
3070.              &prev->upstream, ngx_http_fastcgi_hide_headers, &hash)
3071.         != NGX_OK)

src/http/ngx_http_upstream.c:5936:1: Parameter `hash->max_size`
  5934. 
  5935. 
  5936. ngx_int_t
        ^
  5937. ngx_http_upstream_hide_headers_hash(ngx_conf_t *cf,
  5938.     ngx_http_upstream_conf_t *conf, ngx_http_upstream_conf_t *prev,

src/http/ngx_http_upstream.c:6044:12: Call
  6042.     hash->temp_pool = NULL;
  6043. 
  6044.     return ngx_hash_init(hash, hide_headers.elts, hide_headers.nelts);
                   ^
  6045. }
  6046. 

src/core/ngx_hash.c:251:1: <Offset trace>
249.     (sizeof(void *) + ngx_align((name)->key.len + 2, sizeof(void *)))
250. 
251. ngx_int_t
     ^
252. ngx_hash_init(ngx_hash_init_t *hinit, ngx_hash_key_t *names, ngx_uint_t nelts)
253. {

src/core/ngx_hash.c:251:1: Parameter `hinit->max_size`
    249.     (sizeof(void *) + ngx_align((name)->key.len + 2, sizeof(void *)))
    250. 
    251. ngx_int_t
         ^
    252. ngx_hash_init(ngx_hash_init_t *hinit, ngx_hash_key_t *names, ngx_uint_t nelts)
    253. {

src/core/ngx_hash.c:251:1: <Length trace>
249.     (sizeof(void *) + ngx_align((name)->key.len + 2, sizeof(void *)))
250. 
251. ngx_int_t
     ^
252. ngx_hash_init(ngx_hash_init_t *hinit, ngx_hash_key_t *names, ngx_uint_t nelts)
253. {

src/core/ngx_hash.c:251:1: Parameter `hinit->max_size`
    249.     (sizeof(void *) + ngx_align((name)->key.len + 2, sizeof(void *)))
    250. 
    251. ngx_int_t
         ^
    252. ngx_hash_init(ngx_hash_init_t *hinit, ngx_hash_key_t *names, ngx_uint_t nelts)
    253. {

src/core/ngx_hash.c:371:19: Call
    369. 
    370.     } else {
    371.         buckets = ngx_pcalloc(hinit->pool, size * sizeof(ngx_hash_elt_t *));
                           ^
    372.         if (buckets == NULL) {
    373.             ngx_free(test);

src/core/ngx_palloc.c:297:1: Parameter `size`
      295. 
      296. 
      297. void *
           ^
      298. ngx_pcalloc(ngx_pool_t *pool, size_t size)
      299. {

src/core/ngx_palloc.c:302:9: Call
      300.     void *p;
      301. 
      302.     p = ngx_palloc(pool, size);
                   ^
      303.     if (p) {
      304.         ngx_memzero(p, size);

src/core/ngx_palloc.c:127:16: Call
        125. #if !(NGX_DEBUG_PALLOC)
        126.     if (size <= pool->max) {
        127.         return ngx_palloc_small(pool, size, 1);
                            ^
        128.     }
        129. #endif

src/core/ngx_palloc.c:157:9: Assignment
          155. 
          156.     do {
          157.         m = p->d.last;
                       ^
          158. 
          159.         if (align) {

src/core/ngx_palloc.c:166:13: Assignment
          164.             p->d.last = m + size;
          165. 
          166.             return m;
                           ^
          167.         }
          168. 

src/core/ngx_palloc.c:127:9: Assignment
        125. #if !(NGX_DEBUG_PALLOC)
        126.     if (size <= pool->max) {
        127.         return ngx_palloc_small(pool, size, 1);
                     ^
        128.     }
        129. #endif

src/core/ngx_palloc.c:302:5: Assignment
      300.     void *p;
      301. 
      302.     p = ngx_palloc(pool, size);
               ^
      303.     if (p) {
      304.         ngx_memzero(p, size);

src/core/ngx_palloc.c:307:5: Assignment
      305.     }
      306. 
      307.     return p;
               ^
      308. }
      309. 

src/core/ngx_hash.c:371:9: Assignment
    369. 
    370.     } else {
    371.         buckets = ngx_pcalloc(hinit->pool, size * sizeof(ngx_hash_elt_t *));
                 ^
    372.         if (buckets == NULL) {
    373.             ngx_free(test);

src/core/ngx_hash.c:391:9: Array access: Offset: [0, 535] (⇐ [0, 24] + [0, 511]) Size: [0, 4120] by call to `ngx_http_upstream_hide_headers_hash` 
    389.         }
    390. 
    391.         buckets[i] = (ngx_hash_elt_t *) elts;
                 ^
    392.         elts += test[i];
    393. 

ngx_int_t
ngx_hash_init(ngx_hash_init_t *hinit, ngx_hash_key_t *names, ngx_uint_t nelts)
{
    u_char          *elts;
    size_t           len;
    u_short         *test;
    ngx_uint_t       i, n, key, size, start, bucket_size;
    ngx_hash_elt_t  *elt, **buckets;
    if (hinit->max_size == 0) {
        ngx_log_error(NGX_LOG_EMERG, hinit->pool->log, 0,
                      "could not build %s, you should "
                      "increase %s_max_size: %i",
                      hinit->name, hinit->name, hinit->max_size);
        return NGX_ERROR;
    }
    for (n = 0; n < nelts; n++) {
        if (hinit->bucket_size < NGX_HASH_ELT_SIZE(&names[n]) + sizeof(void *))
        {
            ngx_log_error(NGX_LOG_EMERG, hinit->pool->log, 0,
                          "could not build %s, you should "
                          "increase %s_bucket_size: %i",
                          hinit->name, hinit->name, hinit->bucket_size);
            return NGX_ERROR;
        }
    }
    test = ngx_alloc(hinit->max_size * sizeof(u_short), hinit->pool->log);
    if (test == NULL) {
        return NGX_ERROR;
    }
    bucket_size = hinit->bucket_size - sizeof(void *);
    start = nelts / (bucket_size / (2 * sizeof(void *)));
    start = start ? start : 1;
    if (hinit->max_size > 10000 && nelts && hinit->max_size / nelts < 100) {
        start = hinit->max_size - 1000;
    }
    for (size = start; size <= hinit->max_size; size++) {
        ngx_memzero(test, size * sizeof(u_short));
        for (n = 0; n < nelts; n++) {
            if (names[n].key.data == NULL) {
                continue;
            }
            key = names[n].key_hash % size;
            test[key] = (u_short) (test[key] + NGX_HASH_ELT_SIZE(&names[n]));
#if 0
            ngx_log_error(NGX_LOG_ALERT, hinit->pool->log, 0,
                          "%ui: %ui %ui \"%V\"",
                          size, key, test[key], &names[n].key);
#endif
            if (test[key] > (u_short) bucket_size) {
                goto next;
            }
        }
        goto found;
    next:
        continue;
    }
    size = hinit->max_size;
    ngx_log_error(NGX_LOG_WARN, hinit->pool->log, 0,
                  "could not build optimal %s, you should increase "
                  "either %s_max_size: %i or %s_bucket_size: %i; "
                  "ignoring %s_bucket_size",
                  hinit->name, hinit->name, hinit->max_size,
                  hinit->name, hinit->bucket_size, hinit->name);
found:
    for (i = 0; i < size; i++) {
        test[i] = sizeof(void *);
    }
    for (n = 0; n < nelts; n++) {
        if (names[n].key.data == NULL) {
            continue;
        }
        key = names[n].key_hash % size;
        test[key] = (u_short) (test[key] + NGX_HASH_ELT_SIZE(&names[n]));
    }
    len = 0;
    for (i = 0; i < size; i++) {
        if (test[i] == sizeof(void *)) {
            continue;
        }
        test[i] = (u_short) (ngx_align(test[i], ngx_cacheline_size));
        len += test[i];
    }
    if (hinit->hash == NULL) {
        hinit->hash = ngx_pcalloc(hinit->pool, sizeof(ngx_hash_wildcard_t)
                                             + size * sizeof(ngx_hash_elt_t *));
        if (hinit->hash == NULL) {
            ngx_free(test);
            return NGX_ERROR;
        }
        buckets = (ngx_hash_elt_t **)
                      ((u_char *) hinit->hash + sizeof(ngx_hash_wildcard_t));
    } else {
        buckets = ngx_pcalloc(hinit->pool, size * sizeof(ngx_hash_elt_t *));
        if (buckets == NULL) {
            ngx_free(test);
            return NGX_ERROR;
        }
    }
    elts = ngx_palloc(hinit->pool, len + ngx_cacheline_size);
    if (elts == NULL) {
        ngx_free(test);
        return NGX_ERROR;
    }
    elts = ngx_align_ptr(elts, ngx_cacheline_size);
    for (i = 0; i < size; i++) {
        if (test[i] == sizeof(void *)) {
            continue;
        }
        buckets[i] = (ngx_hash_elt_t *) elts;
        elts += test[i];
    }
    for (i = 0; i < size; i++) {
        test[i] = 0;
    }
    for (n = 0; n < nelts; n++) {
        if (names[n].key.data == NULL) {
            continue;
        }
        key = names[n].key_hash % size;
        elt = (ngx_hash_elt_t *) ((u_char *) buckets[key] + test[key]);
        elt->value = names[n].value;
        elt->len = (u_short) names[n].key.len;
        ngx_strlow(elt->name, names[n].key.data, names[n].key.len);
        test[key] = (u_short) (test[key] + NGX_HASH_ELT_SIZE(&names[n]));
    }
    for (i = 0; i < size; i++) {
        if (buckets[i] == NULL) {
            continue;
        }
        elt = (ngx_hash_elt_t *) ((u_char *) buckets[i] + test[i]);
        elt->value = NULL;
    }
    ngx_free(test);
    hinit->hash->buckets = buckets;
    hinit->hash->size = size;
#if 0
    for (i = 0; i < size; i++) {
        ngx_str_t   val;
        ngx_uint_t  key;
        elt = buckets[i];
        if (elt == NULL) {
            ngx_log_error(NGX_LOG_ALERT, hinit->pool->log, 0,
                          "%ui: NULL", i);
            continue;
        }
        while (elt->value) {
            val.len = elt->len;
            val.data = &elt->name[0];
            key = hinit->key(val.data, val.len);
            ngx_log_error(NGX_LOG_ALERT, hinit->pool->log, 0,
                          "%ui: %p \"%V\" %ui", i, elt, &val, key);
            elt = (ngx_hash_elt_t *) ngx_align_ptr(&elt->name[0] + elt->len,
                                                   sizeof(void *));
        }
    }
#endif
    return NGX_OK;
}
['static char *\nngx_http_fastcgi_merge_loc_conf(ngx_conf_t *cf, void *parent, void *child)\n{\n    ngx_http_fastcgi_loc_conf_t *prev = parent;\n    ngx_http_fastcgi_loc_conf_t *conf = child;\n    size_t                        size;\n    ngx_int_t                     rc;\n    ngx_hash_init_t               hash;\n    ngx_http_core_loc_conf_t     *clcf;\n#if (NGX_HTTP_CACHE)\n    if (conf->upstream.store > 0) {\n        conf->upstream.cache = 0;\n    }\n    if (conf->upstream.cache > 0) {\n        conf->upstream.store = 0;\n    }\n#endif\n    if (conf->upstream.store == NGX_CONF_UNSET) {\n        ngx_conf_merge_value(conf->upstream.store,\n                              prev->upstream.store, 0);\n        conf->upstream.store_lengths = prev->upstream.store_lengths;\n        conf->upstream.store_values = prev->upstream.store_values;\n    }\n    ngx_conf_merge_uint_value(conf->upstream.store_access,\n                              prev->upstream.store_access, 0600);\n    ngx_conf_merge_uint_value(conf->upstream.next_upstream_tries,\n                              prev->upstream.next_upstream_tries, 0);\n    ngx_conf_merge_value(conf->upstream.buffering,\n                              prev->upstream.buffering, 1);\n    ngx_conf_merge_value(conf->upstream.request_buffering,\n                              prev->upstream.request_buffering, 1);\n    ngx_conf_merge_value(conf->upstream.ignore_client_abort,\n                              prev->upstream.ignore_client_abort, 0);\n    ngx_conf_merge_value(conf->upstream.force_ranges,\n                              prev->upstream.force_ranges, 0);\n    ngx_conf_merge_ptr_value(conf->upstream.local,\n                              prev->upstream.local, NULL);\n    ngx_conf_merge_msec_value(conf->upstream.connect_timeout,\n                              prev->upstream.connect_timeout, 60000);\n    ngx_conf_merge_msec_value(conf->upstream.send_timeout,\n                              prev->upstream.send_timeout, 60000);\n    ngx_conf_merge_msec_value(conf->upstream.read_timeout,\n                              prev->upstream.read_timeout, 60000);\n    ngx_conf_merge_msec_value(conf->upstream.next_upstream_timeout,\n                              prev->upstream.next_upstream_timeout, 0);\n    ngx_conf_merge_size_value(conf->upstream.send_lowat,\n                              prev->upstream.send_lowat, 0);\n    ngx_conf_merge_size_value(conf->upstream.buffer_size,\n                              prev->upstream.buffer_size,\n                              (size_t) ngx_pagesize);\n    ngx_conf_merge_size_value(conf->upstream.limit_rate,\n                              prev->upstream.limit_rate, 0);\n    ngx_conf_merge_bufs_value(conf->upstream.bufs, prev->upstream.bufs,\n                              8, ngx_pagesize);\n    if (conf->upstream.bufs.num < 2) {\n        ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,\n                           "there must be at least 2 \\"fastcgi_buffers\\"");\n        return NGX_CONF_ERROR;\n    }\n    size = conf->upstream.buffer_size;\n    if (size < conf->upstream.bufs.size) {\n        size = conf->upstream.bufs.size;\n    }\n    ngx_conf_merge_size_value(conf->upstream.busy_buffers_size_conf,\n                              prev->upstream.busy_buffers_size_conf,\n                              NGX_CONF_UNSET_SIZE);\n    if (conf->upstream.busy_buffers_size_conf == NGX_CONF_UNSET_SIZE) {\n        conf->upstream.busy_buffers_size = 2 * size;\n    } else {\n        conf->upstream.busy_buffers_size =\n                                         conf->upstream.busy_buffers_size_conf;\n    }\n    if (conf->upstream.busy_buffers_size < size) {\n        ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,\n             "\\"fastcgi_busy_buffers_size\\" must be equal to or greater than "\n             "the maximum of the value of \\"fastcgi_buffer_size\\" and "\n             "one of the \\"fastcgi_buffers\\"");\n        return NGX_CONF_ERROR;\n    }\n    if (conf->upstream.busy_buffers_size\n        > (conf->upstream.bufs.num - 1) * conf->upstream.bufs.size)\n    {\n        ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,\n             "\\"fastcgi_busy_buffers_size\\" must be less than "\n             "the size of all \\"fastcgi_buffers\\" minus one buffer");\n        return NGX_CONF_ERROR;\n    }\n    ngx_conf_merge_size_value(conf->upstream.temp_file_write_size_conf,\n                              prev->upstream.temp_file_write_size_conf,\n                              NGX_CONF_UNSET_SIZE);\n    if (conf->upstream.temp_file_write_size_conf == NGX_CONF_UNSET_SIZE) {\n        conf->upstream.temp_file_write_size = 2 * size;\n    } else {\n        conf->upstream.temp_file_write_size =\n                                      conf->upstream.temp_file_write_size_conf;\n    }\n    if (conf->upstream.temp_file_write_size < size) {\n        ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,\n             "\\"fastcgi_temp_file_write_size\\" must be equal to or greater "\n             "than the maximum of the value of \\"fastcgi_buffer_size\\" and "\n             "one of the \\"fastcgi_buffers\\"");\n        return NGX_CONF_ERROR;\n    }\n    ngx_conf_merge_size_value(conf->upstream.max_temp_file_size_conf,\n                              prev->upstream.max_temp_file_size_conf,\n                              NGX_CONF_UNSET_SIZE);\n    if (conf->upstream.max_temp_file_size_conf == NGX_CONF_UNSET_SIZE) {\n        conf->upstream.max_temp_file_size = 1024 * 1024 * 1024;\n    } else {\n        conf->upstream.max_temp_file_size =\n                                        conf->upstream.max_temp_file_size_conf;\n    }\n    if (conf->upstream.max_temp_file_size != 0\n        && conf->upstream.max_temp_file_size < size)\n    {\n        ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,\n             "\\"fastcgi_max_temp_file_size\\" must be equal to zero to disable "\n             "temporary files usage or must be equal to or greater than "\n             "the maximum of the value of \\"fastcgi_buffer_size\\" and "\n             "one of the \\"fastcgi_buffers\\"");\n        return NGX_CONF_ERROR;\n    }\n    ngx_conf_merge_bitmask_value(conf->upstream.ignore_headers,\n                              prev->upstream.ignore_headers,\n                              NGX_CONF_BITMASK_SET);\n    ngx_conf_merge_bitmask_value(conf->upstream.next_upstream,\n                              prev->upstream.next_upstream,\n                              (NGX_CONF_BITMASK_SET\n                               |NGX_HTTP_UPSTREAM_FT_ERROR\n                               |NGX_HTTP_UPSTREAM_FT_TIMEOUT));\n    if (conf->upstream.next_upstream & NGX_HTTP_UPSTREAM_FT_OFF) {\n        conf->upstream.next_upstream = NGX_CONF_BITMASK_SET\n                                       |NGX_HTTP_UPSTREAM_FT_OFF;\n    }\n    if (ngx_conf_merge_path_value(cf, &conf->upstream.temp_path,\n                              prev->upstream.temp_path,\n                              &ngx_http_fastcgi_temp_path)\n        != NGX_OK)\n    {\n        return NGX_CONF_ERROR;\n    }\n#if (NGX_HTTP_CACHE)\n    if (conf->upstream.cache == NGX_CONF_UNSET) {\n        ngx_conf_merge_value(conf->upstream.cache,\n                              prev->upstream.cache, 0);\n        conf->upstream.cache_zone = prev->upstream.cache_zone;\n        conf->upstream.cache_value = prev->upstream.cache_value;\n    }\n    if (conf->upstream.cache_zone && conf->upstream.cache_zone->data == NULL) {\n        ngx_shm_zone_t  *shm_zone;\n        shm_zone = conf->upstream.cache_zone;\n        ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,\n                           "\\"fastcgi_cache\\" zone \\"%V\\" is unknown",\n                           &shm_zone->shm.name);\n        return NGX_CONF_ERROR;\n    }\n    ngx_conf_merge_uint_value(conf->upstream.cache_min_uses,\n                              prev->upstream.cache_min_uses, 1);\n    ngx_conf_merge_bitmask_value(conf->upstream.cache_use_stale,\n                              prev->upstream.cache_use_stale,\n                              (NGX_CONF_BITMASK_SET\n                               |NGX_HTTP_UPSTREAM_FT_OFF));\n    if (conf->upstream.cache_use_stale & NGX_HTTP_UPSTREAM_FT_OFF) {\n        conf->upstream.cache_use_stale = NGX_CONF_BITMASK_SET\n                                         |NGX_HTTP_UPSTREAM_FT_OFF;\n    }\n    if (conf->upstream.cache_use_stale & NGX_HTTP_UPSTREAM_FT_ERROR) {\n        conf->upstream.cache_use_stale |= NGX_HTTP_UPSTREAM_FT_NOLIVE;\n    }\n    if (conf->upstream.cache_methods == 0) {\n        conf->upstream.cache_methods = prev->upstream.cache_methods;\n    }\n    conf->upstream.cache_methods |= NGX_HTTP_GET|NGX_HTTP_HEAD;\n    ngx_conf_merge_ptr_value(conf->upstream.cache_bypass,\n                             prev->upstream.cache_bypass, NULL);\n    ngx_conf_merge_ptr_value(conf->upstream.no_cache,\n                             prev->upstream.no_cache, NULL);\n    ngx_conf_merge_ptr_value(conf->upstream.cache_valid,\n                             prev->upstream.cache_valid, NULL);\n    if (conf->cache_key.value.data == NULL) {\n        conf->cache_key = prev->cache_key;\n    }\n    if (conf->upstream.cache && conf->cache_key.value.data == NULL) {\n        ngx_conf_log_error(NGX_LOG_WARN, cf, 0,\n                           "no \\"fastcgi_cache_key\\" for \\"fastcgi_cache\\"");\n    }\n    ngx_conf_merge_value(conf->upstream.cache_lock,\n                              prev->upstream.cache_lock, 0);\n    ngx_conf_merge_msec_value(conf->upstream.cache_lock_timeout,\n                              prev->upstream.cache_lock_timeout, 5000);\n    ngx_conf_merge_msec_value(conf->upstream.cache_lock_age,\n                              prev->upstream.cache_lock_age, 5000);\n    ngx_conf_merge_value(conf->upstream.cache_revalidate,\n                              prev->upstream.cache_revalidate, 0);\n#endif\n    ngx_conf_merge_value(conf->upstream.pass_request_headers,\n                              prev->upstream.pass_request_headers, 1);\n    ngx_conf_merge_value(conf->upstream.pass_request_body,\n                              prev->upstream.pass_request_body, 1);\n    ngx_conf_merge_value(conf->upstream.intercept_errors,\n                              prev->upstream.intercept_errors, 0);\n    ngx_conf_merge_ptr_value(conf->catch_stderr, prev->catch_stderr, NULL);\n    ngx_conf_merge_value(conf->keep_conn, prev->keep_conn, 0);\n    ngx_conf_merge_str_value(conf->index, prev->index, "");\n    hash.max_size = 512;\n    hash.bucket_size = ngx_align(64, ngx_cacheline_size);\n    hash.name = "fastcgi_hide_headers_hash";\n    if (ngx_http_upstream_hide_headers_hash(cf, &conf->upstream,\n             &prev->upstream, ngx_http_fastcgi_hide_headers, &hash)\n        != NGX_OK)\n    {\n        return NGX_CONF_ERROR;\n    }\n    clcf = ngx_http_conf_get_module_loc_conf(cf, ngx_http_core_module);\n    if (clcf->noname\n        && conf->upstream.upstream == NULL && conf->fastcgi_lengths == NULL)\n    {\n        conf->upstream.upstream = prev->upstream.upstream;\n        conf->fastcgi_lengths = prev->fastcgi_lengths;\n        conf->fastcgi_values = prev->fastcgi_values;\n    }\n    if (clcf->lmt_excpt && clcf->handler == NULL\n        && (conf->upstream.upstream || conf->fastcgi_lengths))\n    {\n        clcf->handler = ngx_http_fastcgi_handler;\n    }\n#if (NGX_PCRE)\n    if (conf->split_regex == NULL) {\n        conf->split_regex = prev->split_regex;\n        conf->split_name = prev->split_name;\n    }\n#endif\n    if (conf->params_source == NULL) {\n        conf->params = prev->params;\n#if (NGX_HTTP_CACHE)\n        conf->params_cache = prev->params_cache;\n#endif\n        conf->params_source = prev->params_source;\n    }\n    rc = ngx_http_fastcgi_init_params(cf, conf, &conf->params, NULL);\n    if (rc != NGX_OK) {\n        return NGX_CONF_ERROR;\n    }\n#if (NGX_HTTP_CACHE)\n    if (conf->upstream.cache) {\n        rc = ngx_http_fastcgi_init_params(cf, conf, &conf->params_cache,\n                                          ngx_http_fastcgi_cache_headers);\n        if (rc != NGX_OK) {\n            return NGX_CONF_ERROR;\n        }\n    }\n#endif\n    return NGX_CONF_OK;\n}', 'ngx_int_t\nngx_http_upstream_hide_headers_hash(ngx_conf_t *cf,\n    ngx_http_upstream_conf_t *conf, ngx_http_upstream_conf_t *prev,\n    ngx_str_t *default_hide_headers, ngx_hash_init_t *hash)\n{\n    ngx_str_t       *h;\n    ngx_uint_t       i, j;\n    ngx_array_t      hide_headers;\n    ngx_hash_key_t  *hk;\n    if (conf->hide_headers == NGX_CONF_UNSET_PTR\n        && conf->pass_headers == NGX_CONF_UNSET_PTR)\n    {\n        conf->hide_headers = prev->hide_headers;\n        conf->pass_headers = prev->pass_headers;\n        conf->hide_headers_hash = prev->hide_headers_hash;\n        if (conf->hide_headers_hash.buckets\n#if (NGX_HTTP_CACHE)\n            && ((conf->cache == 0) == (prev->cache == 0))\n#endif\n           )\n        {\n            return NGX_OK;\n        }\n    } else {\n        if (conf->hide_headers == NGX_CONF_UNSET_PTR) {\n            conf->hide_headers = prev->hide_headers;\n        }\n        if (conf->pass_headers == NGX_CONF_UNSET_PTR) {\n            conf->pass_headers = prev->pass_headers;\n        }\n    }\n    if (ngx_array_init(&hide_headers, cf->temp_pool, 4, sizeof(ngx_hash_key_t))\n        != NGX_OK)\n    {\n        return NGX_ERROR;\n    }\n    for (h = default_hide_headers; h->len; h++) {\n        hk = ngx_array_push(&hide_headers);\n        if (hk == NULL) {\n            return NGX_ERROR;\n        }\n        hk->key = *h;\n        hk->key_hash = ngx_hash_key_lc(h->data, h->len);\n        hk->value = (void *) 1;\n    }\n    if (conf->hide_headers != NGX_CONF_UNSET_PTR) {\n        h = conf->hide_headers->elts;\n        for (i = 0; i < conf->hide_headers->nelts; i++) {\n            hk = hide_headers.elts;\n            for (j = 0; j < hide_headers.nelts; j++) {\n                if (ngx_strcasecmp(h[i].data, hk[j].key.data) == 0) {\n                    goto exist;\n                }\n            }\n            hk = ngx_array_push(&hide_headers);\n            if (hk == NULL) {\n                return NGX_ERROR;\n            }\n            hk->key = h[i];\n            hk->key_hash = ngx_hash_key_lc(h[i].data, h[i].len);\n            hk->value = (void *) 1;\n        exist:\n            continue;\n        }\n    }\n    if (conf->pass_headers != NGX_CONF_UNSET_PTR) {\n        h = conf->pass_headers->elts;\n        hk = hide_headers.elts;\n        for (i = 0; i < conf->pass_headers->nelts; i++) {\n            for (j = 0; j < hide_headers.nelts; j++) {\n                if (hk[j].key.data == NULL) {\n                    continue;\n                }\n                if (ngx_strcasecmp(h[i].data, hk[j].key.data) == 0) {\n                    hk[j].key.data = NULL;\n                    break;\n                }\n            }\n        }\n    }\n    hash->hash = &conf->hide_headers_hash;\n    hash->key = ngx_hash_key_lc;\n    hash->pool = cf->pool;\n    hash->temp_pool = NULL;\n    return ngx_hash_init(hash, hide_headers.elts, hide_headers.nelts);\n}', 'ngx_int_t\nngx_hash_init(ngx_hash_init_t *hinit, ngx_hash_key_t *names, ngx_uint_t nelts)\n{\n    u_char          *elts;\n    size_t           len;\n    u_short         *test;\n    ngx_uint_t       i, n, key, size, start, bucket_size;\n    ngx_hash_elt_t  *elt, **buckets;\n    if (hinit->max_size == 0) {\n        ngx_log_error(NGX_LOG_EMERG, hinit->pool->log, 0,\n                      "could not build %s, you should "\n                      "increase %s_max_size: %i",\n                      hinit->name, hinit->name, hinit->max_size);\n        return NGX_ERROR;\n    }\n    for (n = 0; n < nelts; n++) {\n        if (hinit->bucket_size < NGX_HASH_ELT_SIZE(&names[n]) + sizeof(void *))\n        {\n            ngx_log_error(NGX_LOG_EMERG, hinit->pool->log, 0,\n                          "could not build %s, you should "\n                          "increase %s_bucket_size: %i",\n                          hinit->name, hinit->name, hinit->bucket_size);\n            return NGX_ERROR;\n        }\n    }\n    test = ngx_alloc(hinit->max_size * sizeof(u_short), hinit->pool->log);\n    if (test == NULL) {\n        return NGX_ERROR;\n    }\n    bucket_size = hinit->bucket_size - sizeof(void *);\n    start = nelts / (bucket_size / (2 * sizeof(void *)));\n    start = start ? start : 1;\n    if (hinit->max_size > 10000 && nelts && hinit->max_size / nelts < 100) {\n        start = hinit->max_size - 1000;\n    }\n    for (size = start; size <= hinit->max_size; size++) {\n        ngx_memzero(test, size * sizeof(u_short));\n        for (n = 0; n < nelts; n++) {\n            if (names[n].key.data == NULL) {\n                continue;\n            }\n            key = names[n].key_hash % size;\n            test[key] = (u_short) (test[key] + NGX_HASH_ELT_SIZE(&names[n]));\n#if 0\n            ngx_log_error(NGX_LOG_ALERT, hinit->pool->log, 0,\n                          "%ui: %ui %ui \\"%V\\"",\n                          size, key, test[key], &names[n].key);\n#endif\n            if (test[key] > (u_short) bucket_size) {\n                goto next;\n            }\n        }\n        goto found;\n    next:\n        continue;\n    }\n    size = hinit->max_size;\n    ngx_log_error(NGX_LOG_WARN, hinit->pool->log, 0,\n                  "could not build optimal %s, you should increase "\n                  "either %s_max_size: %i or %s_bucket_size: %i; "\n                  "ignoring %s_bucket_size",\n                  hinit->name, hinit->name, hinit->max_size,\n                  hinit->name, hinit->bucket_size, hinit->name);\nfound:\n    for (i = 0; i < size; i++) {\n        test[i] = sizeof(void *);\n    }\n    for (n = 0; n < nelts; n++) {\n        if (names[n].key.data == NULL) {\n            continue;\n        }\n        key = names[n].key_hash % size;\n        test[key] = (u_short) (test[key] + NGX_HASH_ELT_SIZE(&names[n]));\n    }\n    len = 0;\n    for (i = 0; i < size; i++) {\n        if (test[i] == sizeof(void *)) {\n            continue;\n        }\n        test[i] = (u_short) (ngx_align(test[i], ngx_cacheline_size));\n        len += test[i];\n    }\n    if (hinit->hash == NULL) {\n        hinit->hash = ngx_pcalloc(hinit->pool, sizeof(ngx_hash_wildcard_t)\n                                             + size * sizeof(ngx_hash_elt_t *));\n        if (hinit->hash == NULL) {\n            ngx_free(test);\n            return NGX_ERROR;\n        }\n        buckets = (ngx_hash_elt_t **)\n                      ((u_char *) hinit->hash + sizeof(ngx_hash_wildcard_t));\n    } else {\n        buckets = ngx_pcalloc(hinit->pool, size * sizeof(ngx_hash_elt_t *));\n        if (buckets == NULL) {\n            ngx_free(test);\n            return NGX_ERROR;\n        }\n    }\n    elts = ngx_palloc(hinit->pool, len + ngx_cacheline_size);\n    if (elts == NULL) {\n        ngx_free(test);\n        return NGX_ERROR;\n    }\n    elts = ngx_align_ptr(elts, ngx_cacheline_size);\n    for (i = 0; i < size; i++) {\n        if (test[i] == sizeof(void *)) {\n            continue;\n        }\n        buckets[i] = (ngx_hash_elt_t *) elts;\n        elts += test[i];\n    }\n    for (i = 0; i < size; i++) {\n        test[i] = 0;\n    }\n    for (n = 0; n < nelts; n++) {\n        if (names[n].key.data == NULL) {\n            continue;\n        }\n        key = names[n].key_hash % size;\n        elt = (ngx_hash_elt_t *) ((u_char *) buckets[key] + test[key]);\n        elt->value = names[n].value;\n        elt->len = (u_short) names[n].key.len;\n        ngx_strlow(elt->name, names[n].key.data, names[n].key.len);\n        test[key] = (u_short) (test[key] + NGX_HASH_ELT_SIZE(&names[n]));\n    }\n    for (i = 0; i < size; i++) {\n        if (buckets[i] == NULL) {\n            continue;\n        }\n        elt = (ngx_hash_elt_t *) ((u_char *) buckets[i] + test[i]);\n        elt->value = NULL;\n    }\n    ngx_free(test);\n    hinit->hash->buckets = buckets;\n    hinit->hash->size = size;\n#if 0\n    for (i = 0; i < size; i++) {\n        ngx_str_t   val;\n        ngx_uint_t  key;\n        elt = buckets[i];\n        if (elt == NULL) {\n            ngx_log_error(NGX_LOG_ALERT, hinit->pool->log, 0,\n                          "%ui: NULL", i);\n            continue;\n        }\n        while (elt->value) {\n            val.len = elt->len;\n            val.data = &elt->name[0];\n            key = hinit->key(val.data, val.len);\n            ngx_log_error(NGX_LOG_ALERT, hinit->pool->log, 0,\n                          "%ui: %p \\"%V\\" %ui", i, elt, &val, key);\n            elt = (ngx_hash_elt_t *) ngx_align_ptr(&elt->name[0] + elt->len,\n                                                   sizeof(void *));\n        }\n    }\n#endif\n    return NGX_OK;\n}', 'void *\nngx_pcalloc(ngx_pool_t *pool, size_t size)\n{\n    void *p;\n    p = ngx_palloc(pool, size);\n    if (p) {\n        ngx_memzero(p, size);\n    }\n    return p;\n}', 'void *\nngx_palloc(ngx_pool_t *pool, size_t size)\n{\n#if !(NGX_DEBUG_PALLOC)\n    if (size <= pool->max) {\n        return ngx_palloc_small(pool, size, 1);\n    }\n#endif\n    return ngx_palloc_large(pool, size);\n}', 'static ngx_inline void *\nngx_palloc_small(ngx_pool_t *pool, size_t size, ngx_uint_t align)\n{\n    u_char      *m;\n    ngx_pool_t  *p;\n    p = pool->current;\n    do {\n        m = p->d.last;\n        if (align) {\n            m = ngx_align_ptr(m, NGX_ALIGNMENT);\n        }\n        if ((size_t) (p->d.end - m) >= size) {\n            p->d.last = m + size;\n            return m;\n        }\n        p = p->d.next;\n    } while (p);\n    return ngx_palloc_block(pool, size);\n}']