src/http/modules/ngx_http_limit_conn_module.c:234: error: Integer Overflow L2
  ([0, 291] - 1):unsigned64 by call to `ngx_slab_alloc_locked`.

src/http/modules/ngx_http_limit_conn_module.c:204:13: Call
202.         ctx = limits[i].shm_zone->data;
203. 
204.         if (ngx_http_complex_value(r, &ctx->key, &key) != NGX_OK) {
                 ^
205.             return NGX_HTTP_INTERNAL_SERVER_ERROR;
206.         }

src/http/ngx_http_script.c:57:1: Parameter `value->len`
  55. 
  56. 
  57. ngx_int_t
      ^
  58. ngx_http_complex_value(ngx_http_request_t *r, ngx_http_complex_value_t *val,
  59.     ngx_str_t *value)

src/http/modules/ngx_http_limit_conn_module.c:230:13: Assignment
228.         if (node == NULL) {
229. 
230.             n = offsetof(ngx_rbtree_node_t, color)
                 ^
231.                 + offsetof(ngx_http_limit_conn_node_t, data)
232.                 + key.len;

src/http/modules/ngx_http_limit_conn_module.c:234:20: Call
232.                 + key.len;
233. 
234.             node = ngx_slab_alloc_locked(ctx->shpool, n);
                        ^
235. 
236.             if (node == NULL) {

src/core/ngx_slab.c:183:1: <LHS trace>
181. 
182. 
183. void *
     ^
184. ngx_slab_alloc_locked(ngx_slab_pool_t *pool, size_t size)
185. {

src/core/ngx_slab.c:183:1: Global `ngx_slab_max_size`
  181. 
  182. 
  183. void *
       ^
  184. ngx_slab_alloc_locked(ngx_slab_pool_t *pool, size_t size)
  185. {

src/core/ngx_slab.c:210:14: Binary operation: ([0, 291] - 1):unsigned64 by call to `ngx_slab_alloc_locked` 
  208.     if (size > pool->min_size) {
  209.         shift = 1;
  210.         for (s = size - 1; s >>= 1; shift++) { /* void */ }
                    ^
  211.         slot = shift - pool->min_shift;
  212. 

void *
ngx_slab_alloc_locked(ngx_slab_pool_t *pool, size_t size)
{
    size_t            s;
    uintptr_t         p, m, mask, *bitmap;
    ngx_uint_t        i, n, slot, shift, map;
    ngx_slab_page_t  *page, *prev, *slots;
    if (size > ngx_slab_max_size) {
        ngx_log_debug1(NGX_LOG_DEBUG_ALLOC, ngx_cycle->log, 0,
                       "slab alloc: %uz", size);
        page = ngx_slab_alloc_pages(pool, (size >> ngx_pagesize_shift)
                                          + ((size % ngx_pagesize) ? 1 : 0));
        if (page) {
            p = ngx_slab_page_addr(pool, page);
        } else {
            p = 0;
        }
        goto done;
    }
    if (size > pool->min_size) {
        shift = 1;
        for (s = size - 1; s >>= 1; shift++) {   }
        slot = shift - pool->min_shift;
    } else {
        shift = pool->min_shift;
        slot = 0;
    }
    pool->stats[slot].reqs++;
    ngx_log_debug2(NGX_LOG_DEBUG_ALLOC, ngx_cycle->log, 0,
                   "slab alloc: %uz slot: %ui", size, slot);
    slots = ngx_slab_slots(pool);
    page = slots[slot].next;
    if (page->next != page) {
        if (shift < ngx_slab_exact_shift) {
            bitmap = (uintptr_t *) ngx_slab_page_addr(pool, page);
            map = (ngx_pagesize >> shift) / (8 * sizeof(uintptr_t));
            for (n = 0; n < map; n++) {
                if (bitmap[n] != NGX_SLAB_BUSY) {
                    for (m = 1, i = 0; m; m <<= 1, i++) {
                        if (bitmap[n] & m) {
                            continue;
                        }
                        bitmap[n] |= m;
                        i = (n * 8 * sizeof(uintptr_t) + i) << shift;
                        p = (uintptr_t) bitmap + i;
                        pool->stats[slot].used++;
                        if (bitmap[n] == NGX_SLAB_BUSY) {
                            for (n = n + 1; n < map; n++) {
                                if (bitmap[n] != NGX_SLAB_BUSY) {
                                    goto done;
                                }
                            }
                            prev = ngx_slab_page_prev(page);
                            prev->next = page->next;
                            page->next->prev = page->prev;
                            page->next = NULL;
                            page->prev = NGX_SLAB_SMALL;
                        }
                        goto done;
                    }
                }
            }
        } else if (shift == ngx_slab_exact_shift) {
            for (m = 1, i = 0; m; m <<= 1, i++) {
                if (page->slab & m) {
                    continue;
                }
                page->slab |= m;
                if (page->slab == NGX_SLAB_BUSY) {
                    prev = ngx_slab_page_prev(page);
                    prev->next = page->next;
                    page->next->prev = page->prev;
                    page->next = NULL;
                    page->prev = NGX_SLAB_EXACT;
                }
                p = ngx_slab_page_addr(pool, page) + (i << shift);
                pool->stats[slot].used++;
                goto done;
            }
        } else {
            mask = ((uintptr_t) 1 << (ngx_pagesize >> shift)) - 1;
            mask <<= NGX_SLAB_MAP_SHIFT;
            for (m = (uintptr_t) 1 << NGX_SLAB_MAP_SHIFT, i = 0;
                 m & mask;
                 m <<= 1, i++)
            {
                if (page->slab & m) {
                    continue;
                }
                page->slab |= m;
                if ((page->slab & NGX_SLAB_MAP_MASK) == mask) {
                    prev = ngx_slab_page_prev(page);
                    prev->next = page->next;
                    page->next->prev = page->prev;
                    page->next = NULL;
                    page->prev = NGX_SLAB_BIG;
                }
                p = ngx_slab_page_addr(pool, page) + (i << shift);
                pool->stats[slot].used++;
                goto done;
            }
        }
        ngx_slab_error(pool, NGX_LOG_ALERT, "ngx_slab_alloc(): page is busy");
        ngx_debug_point();
    }
    page = ngx_slab_alloc_pages(pool, 1);
    if (page) {
        if (shift < ngx_slab_exact_shift) {
            bitmap = (uintptr_t *) ngx_slab_page_addr(pool, page);
            n = (ngx_pagesize >> shift) / ((1 << shift) * 8);
            if (n == 0) {
                n = 1;
            }
            for (i = 0; i < (n + 1) / (8 * sizeof(uintptr_t)); i++) {
                bitmap[i] = NGX_SLAB_BUSY;
            }
            m = ((uintptr_t) 1 << ((n + 1) % (8 * sizeof(uintptr_t)))) - 1;
            bitmap[i] = m;
            map = (ngx_pagesize >> shift) / (8 * sizeof(uintptr_t));
            for (i = i + 1; i < map; i++) {
                bitmap[i] = 0;
            }
            page->slab = shift;
            page->next = &slots[slot];
            page->prev = (uintptr_t) &slots[slot] | NGX_SLAB_SMALL;
            slots[slot].next = page;
            pool->stats[slot].total += (ngx_pagesize >> shift) - n;
            p = ngx_slab_page_addr(pool, page) + (n << shift);
            pool->stats[slot].used++;
            goto done;
        } else if (shift == ngx_slab_exact_shift) {
            page->slab = 1;
            page->next = &slots[slot];
            page->prev = (uintptr_t) &slots[slot] | NGX_SLAB_EXACT;
            slots[slot].next = page;
            pool->stats[slot].total += 8 * sizeof(uintptr_t);
            p = ngx_slab_page_addr(pool, page);
            pool->stats[slot].used++;
            goto done;
        } else {
            page->slab = ((uintptr_t) 1 << NGX_SLAB_MAP_SHIFT) | shift;
            page->next = &slots[slot];
            page->prev = (uintptr_t) &slots[slot] | NGX_SLAB_BIG;
            slots[slot].next = page;
            pool->stats[slot].total += ngx_pagesize >> shift;
            p = ngx_slab_page_addr(pool, page);
            pool->stats[slot].used++;
            goto done;
        }
    }
    p = 0;
    pool->stats[slot].fails++;
done:
    ngx_log_debug1(NGX_LOG_DEBUG_ALLOC, ngx_cycle->log, 0,
                   "slab alloc: %p", (void *) p);
    return (void *) p;
}
['static ngx_int_t\nngx_http_limit_conn_handler(ngx_http_request_t *r)\n{\n    size_t                          n;\n    uint32_t                        hash;\n    ngx_str_t                       key;\n    ngx_uint_t                      i;\n    ngx_rbtree_node_t              *node;\n    ngx_pool_cleanup_t             *cln;\n    ngx_http_limit_conn_ctx_t      *ctx;\n    ngx_http_limit_conn_node_t     *lc;\n    ngx_http_limit_conn_conf_t     *lccf;\n    ngx_http_limit_conn_limit_t    *limits;\n    ngx_http_limit_conn_cleanup_t  *lccln;\n    if (r->main->limit_conn_status) {\n        return NGX_DECLINED;\n    }\n    lccf = ngx_http_get_module_loc_conf(r, ngx_http_limit_conn_module);\n    limits = lccf->limits.elts;\n    for (i = 0; i < lccf->limits.nelts; i++) {\n        ctx = limits[i].shm_zone->data;\n        if (ngx_http_complex_value(r, &ctx->key, &key) != NGX_OK) {\n            return NGX_HTTP_INTERNAL_SERVER_ERROR;\n        }\n        if (key.len == 0) {\n            continue;\n        }\n        if (key.len > 255) {\n            ngx_log_error(NGX_LOG_ERR, r->connection->log, 0,\n                          "the value of the \\"%V\\" key "\n                          "is more than 255 bytes: \\"%V\\"",\n                          &ctx->key.value, &key);\n            continue;\n        }\n        r->main->limit_conn_status = NGX_HTTP_LIMIT_CONN_PASSED;\n        hash = ngx_crc32_short(key.data, key.len);\n        ngx_shmtx_lock(&ctx->shpool->mutex);\n        node = ngx_http_limit_conn_lookup(&ctx->sh->rbtree, &key, hash);\n        if (node == NULL) {\n            n = offsetof(ngx_rbtree_node_t, color)\n                + offsetof(ngx_http_limit_conn_node_t, data)\n                + key.len;\n            node = ngx_slab_alloc_locked(ctx->shpool, n);\n            if (node == NULL) {\n                ngx_shmtx_unlock(&ctx->shpool->mutex);\n                ngx_http_limit_conn_cleanup_all(r->pool);\n                if (lccf->dry_run) {\n                    r->main->limit_conn_status =\n                                          NGX_HTTP_LIMIT_CONN_REJECTED_DRY_RUN;\n                    return NGX_DECLINED;\n                }\n                r->main->limit_conn_status = NGX_HTTP_LIMIT_CONN_REJECTED;\n                return lccf->status_code;\n            }\n            lc = (ngx_http_limit_conn_node_t *) &node->color;\n            node->key = hash;\n            lc->len = (u_char) key.len;\n            lc->conn = 1;\n            ngx_memcpy(lc->data, key.data, key.len);\n            ngx_rbtree_insert(&ctx->sh->rbtree, node);\n        } else {\n            lc = (ngx_http_limit_conn_node_t *) &node->color;\n            if ((ngx_uint_t) lc->conn >= limits[i].conn) {\n                ngx_shmtx_unlock(&ctx->shpool->mutex);\n                ngx_log_error(lccf->log_level, r->connection->log, 0,\n                              "limiting connections%s by zone \\"%V\\"",\n                              lccf->dry_run ? ", dry run," : "",\n                              &limits[i].shm_zone->shm.name);\n                ngx_http_limit_conn_cleanup_all(r->pool);\n                if (lccf->dry_run) {\n                    r->main->limit_conn_status =\n                                          NGX_HTTP_LIMIT_CONN_REJECTED_DRY_RUN;\n                    return NGX_DECLINED;\n                }\n                r->main->limit_conn_status = NGX_HTTP_LIMIT_CONN_REJECTED;\n                return lccf->status_code;\n            }\n            lc->conn++;\n        }\n        ngx_log_debug2(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,\n                       "limit conn: %08Xi %d", node->key, lc->conn);\n        ngx_shmtx_unlock(&ctx->shpool->mutex);\n        cln = ngx_pool_cleanup_add(r->pool,\n                                   sizeof(ngx_http_limit_conn_cleanup_t));\n        if (cln == NULL) {\n            return NGX_HTTP_INTERNAL_SERVER_ERROR;\n        }\n        cln->handler = ngx_http_limit_conn_cleanup;\n        lccln = cln->data;\n        lccln->shm_zone = limits[i].shm_zone;\n        lccln->node = node;\n    }\n    return NGX_DECLINED;\n}', 'ngx_int_t\nngx_http_complex_value(ngx_http_request_t *r, ngx_http_complex_value_t *val,\n    ngx_str_t *value)\n{\n    size_t                        len;\n    ngx_http_script_code_pt       code;\n    ngx_http_script_len_code_pt   lcode;\n    ngx_http_script_engine_t      e;\n    if (val->lengths == NULL) {\n        *value = val->value;\n        return NGX_OK;\n    }\n    ngx_http_script_flush_complex_value(r, val);\n    ngx_memzero(&e, sizeof(ngx_http_script_engine_t));\n    e.ip = val->lengths;\n    e.request = r;\n    e.flushed = 1;\n    len = 0;\n    while (*(uintptr_t *) e.ip) {\n        lcode = *(ngx_http_script_len_code_pt *) e.ip;\n        len += lcode(&e);\n    }\n    value->len = len;\n    value->data = ngx_pnalloc(r->pool, len);\n    if (value->data == NULL) {\n        return NGX_ERROR;\n    }\n    e.ip = val->values;\n    e.pos = value->data;\n    e.buf = *value;\n    while (*(uintptr_t *) e.ip) {\n        code = *(ngx_http_script_code_pt *) e.ip;\n        code((ngx_http_script_engine_t *) &e);\n    }\n    *value = e.buf;\n    return NGX_OK;\n}', 'void *\nngx_slab_alloc_locked(ngx_slab_pool_t *pool, size_t size)\n{\n    size_t            s;\n    uintptr_t         p, m, mask, *bitmap;\n    ngx_uint_t        i, n, slot, shift, map;\n    ngx_slab_page_t  *page, *prev, *slots;\n    if (size > ngx_slab_max_size) {\n        ngx_log_debug1(NGX_LOG_DEBUG_ALLOC, ngx_cycle->log, 0,\n                       "slab alloc: %uz", size);\n        page = ngx_slab_alloc_pages(pool, (size >> ngx_pagesize_shift)\n                                          + ((size % ngx_pagesize) ? 1 : 0));\n        if (page) {\n            p = ngx_slab_page_addr(pool, page);\n        } else {\n            p = 0;\n        }\n        goto done;\n    }\n    if (size > pool->min_size) {\n        shift = 1;\n        for (s = size - 1; s >>= 1; shift++) {   }\n        slot = shift - pool->min_shift;\n    } else {\n        shift = pool->min_shift;\n        slot = 0;\n    }\n    pool->stats[slot].reqs++;\n    ngx_log_debug2(NGX_LOG_DEBUG_ALLOC, ngx_cycle->log, 0,\n                   "slab alloc: %uz slot: %ui", size, slot);\n    slots = ngx_slab_slots(pool);\n    page = slots[slot].next;\n    if (page->next != page) {\n        if (shift < ngx_slab_exact_shift) {\n            bitmap = (uintptr_t *) ngx_slab_page_addr(pool, page);\n            map = (ngx_pagesize >> shift) / (8 * sizeof(uintptr_t));\n            for (n = 0; n < map; n++) {\n                if (bitmap[n] != NGX_SLAB_BUSY) {\n                    for (m = 1, i = 0; m; m <<= 1, i++) {\n                        if (bitmap[n] & m) {\n                            continue;\n                        }\n                        bitmap[n] |= m;\n                        i = (n * 8 * sizeof(uintptr_t) + i) << shift;\n                        p = (uintptr_t) bitmap + i;\n                        pool->stats[slot].used++;\n                        if (bitmap[n] == NGX_SLAB_BUSY) {\n                            for (n = n + 1; n < map; n++) {\n                                if (bitmap[n] != NGX_SLAB_BUSY) {\n                                    goto done;\n                                }\n                            }\n                            prev = ngx_slab_page_prev(page);\n                            prev->next = page->next;\n                            page->next->prev = page->prev;\n                            page->next = NULL;\n                            page->prev = NGX_SLAB_SMALL;\n                        }\n                        goto done;\n                    }\n                }\n            }\n        } else if (shift == ngx_slab_exact_shift) {\n            for (m = 1, i = 0; m; m <<= 1, i++) {\n                if (page->slab & m) {\n                    continue;\n                }\n                page->slab |= m;\n                if (page->slab == NGX_SLAB_BUSY) {\n                    prev = ngx_slab_page_prev(page);\n                    prev->next = page->next;\n                    page->next->prev = page->prev;\n                    page->next = NULL;\n                    page->prev = NGX_SLAB_EXACT;\n                }\n                p = ngx_slab_page_addr(pool, page) + (i << shift);\n                pool->stats[slot].used++;\n                goto done;\n            }\n        } else {\n            mask = ((uintptr_t) 1 << (ngx_pagesize >> shift)) - 1;\n            mask <<= NGX_SLAB_MAP_SHIFT;\n            for (m = (uintptr_t) 1 << NGX_SLAB_MAP_SHIFT, i = 0;\n                 m & mask;\n                 m <<= 1, i++)\n            {\n                if (page->slab & m) {\n                    continue;\n                }\n                page->slab |= m;\n                if ((page->slab & NGX_SLAB_MAP_MASK) == mask) {\n                    prev = ngx_slab_page_prev(page);\n                    prev->next = page->next;\n                    page->next->prev = page->prev;\n                    page->next = NULL;\n                    page->prev = NGX_SLAB_BIG;\n                }\n                p = ngx_slab_page_addr(pool, page) + (i << shift);\n                pool->stats[slot].used++;\n                goto done;\n            }\n        }\n        ngx_slab_error(pool, NGX_LOG_ALERT, "ngx_slab_alloc(): page is busy");\n        ngx_debug_point();\n    }\n    page = ngx_slab_alloc_pages(pool, 1);\n    if (page) {\n        if (shift < ngx_slab_exact_shift) {\n            bitmap = (uintptr_t *) ngx_slab_page_addr(pool, page);\n            n = (ngx_pagesize >> shift) / ((1 << shift) * 8);\n            if (n == 0) {\n                n = 1;\n            }\n            for (i = 0; i < (n + 1) / (8 * sizeof(uintptr_t)); i++) {\n                bitmap[i] = NGX_SLAB_BUSY;\n            }\n            m = ((uintptr_t) 1 << ((n + 1) % (8 * sizeof(uintptr_t)))) - 1;\n            bitmap[i] = m;\n            map = (ngx_pagesize >> shift) / (8 * sizeof(uintptr_t));\n            for (i = i + 1; i < map; i++) {\n                bitmap[i] = 0;\n            }\n            page->slab = shift;\n            page->next = &slots[slot];\n            page->prev = (uintptr_t) &slots[slot] | NGX_SLAB_SMALL;\n            slots[slot].next = page;\n            pool->stats[slot].total += (ngx_pagesize >> shift) - n;\n            p = ngx_slab_page_addr(pool, page) + (n << shift);\n            pool->stats[slot].used++;\n            goto done;\n        } else if (shift == ngx_slab_exact_shift) {\n            page->slab = 1;\n            page->next = &slots[slot];\n            page->prev = (uintptr_t) &slots[slot] | NGX_SLAB_EXACT;\n            slots[slot].next = page;\n            pool->stats[slot].total += 8 * sizeof(uintptr_t);\n            p = ngx_slab_page_addr(pool, page);\n            pool->stats[slot].used++;\n            goto done;\n        } else {\n            page->slab = ((uintptr_t) 1 << NGX_SLAB_MAP_SHIFT) | shift;\n            page->next = &slots[slot];\n            page->prev = (uintptr_t) &slots[slot] | NGX_SLAB_BIG;\n            slots[slot].next = page;\n            pool->stats[slot].total += ngx_pagesize >> shift;\n            p = ngx_slab_page_addr(pool, page);\n            pool->stats[slot].used++;\n            goto done;\n        }\n    }\n    p = 0;\n    pool->stats[slot].fails++;\ndone:\n    ngx_log_debug1(NGX_LOG_DEBUG_ALLOC, ngx_cycle->log, 0,\n                   "slab alloc: %p", (void *) p);\n    return (void *) p;\n}']