diff options
author | Morgan Deters <mdeters@cs.nyu.edu> | 2013-02-04 18:11:09 -0500 |
---|---|---|
committer | Morgan Deters <mdeters@cs.nyu.edu> | 2013-02-04 18:11:09 -0500 |
commit | ef0e079d85b18fd36b4d90be15b465e2316a38c9 (patch) | |
tree | 21f9e41c1ca44dd3dfd13846032c9316ec6dd47c /src/expr/node_builder.h | |
parent | 00514e3804ebde7053ba095c678625a9035dc5e3 (diff) |
Fix NodeBuilder bug which could attempt to allocate beyond hard limit
Diffstat (limited to 'src/expr/node_builder.h')
-rw-r--r-- | src/expr/node_builder.h | 25 |
1 files changed, 19 insertions, 6 deletions
diff --git a/src/expr/node_builder.h b/src/expr/node_builder.h index f6aa1920d..458bd25fa 100644 --- a/src/expr/node_builder.h +++ b/src/expr/node_builder.h @@ -1,11 +1,11 @@ /********************* */ /*! \file node_builder.h ** \verbatim - ** Original author: mdeters - ** Major contributors: dejan - ** Minor contributors (to current version): taking, cconway - ** This file is part of the CVC4 prototype. - ** Copyright (c) 2009-2012 New York University and The University of Iowa + ** Original author: Dejan Jovanović <dejan.jovanovic@gmail.com> + ** Major contributors: Morgan Deters <mdeters@cs.nyu.edu> + ** Minor contributors (to current version): Tim King <taking@cs.nyu.edu>, Christopher L. Conway <christopherleeconway@gmail.com> + ** This file is part of the CVC4 project. + ** Copyright (c) 2009-2013 New York University and The University of Iowa ** See the file COPYING in the top-level source directory for licensing ** information.\endverbatim ** @@ -277,7 +277,9 @@ class NodeBuilder { * double-decremented later (on destruction/clear). */ inline void realloc() { - realloc(d_nvMaxChildren * 2); + size_t newSize = 2 * size_t(d_nvMaxChildren); + size_t hardLimit = (1lu << __CVC4__EXPR__NODE_VALUE__NBITS__NCHILDREN) - 1; + realloc(EXPECT_FALSE( newSize > hardLimit ) ? hardLimit : newSize); } /** @@ -662,6 +664,7 @@ public: expr::NodeValue* nv = n.d_nv; nv->inc(); d_nv->d_children[d_nv->d_nchildren++] = nv; + Assert(d_nv->d_nchildren <= d_nvMaxChildren); return *this; } @@ -674,6 +677,7 @@ public: expr::NodeValue* nv = typeNode.d_nv; nv->inc(); d_nv->d_children[d_nv->d_nchildren++] = nv; + Assert(d_nv->d_nchildren <= d_nvMaxChildren); return *this; } @@ -771,6 +775,9 @@ template <unsigned nchild_thresh> void NodeBuilder<nchild_thresh>::realloc(size_t toSize) { Assert( toSize > d_nvMaxChildren, "attempt to realloc() a NodeBuilder to a smaller/equal size!" ); + Assert( toSize < (1lu << __CVC4__EXPR__NODE_VALUE__NBITS__NCHILDREN), + "attempt to realloc() a NodeBuilder to size %u (beyond hard limit of %u)", + toSize, (1lu << __CVC4__EXPR__NODE_VALUE__NBITS__NCHILDREN) - 1 ); if(EXPECT_FALSE( nvIsAllocated() )) { // Ensure d_nv is not modified on allocation failure @@ -783,6 +790,7 @@ void NodeBuilder<nchild_thresh>::realloc(size_t toSize) { throw std::bad_alloc(); } d_nvMaxChildren = toSize; + Assert(d_nvMaxChildren == toSize);//overflow check // Here, the copy (between two heap-allocated buffers) has already // been done for us by the std::realloc(). d_nv = newBlock; @@ -795,6 +803,7 @@ void NodeBuilder<nchild_thresh>::realloc(size_t toSize) { throw std::bad_alloc(); } d_nvMaxChildren = toSize; + Assert(d_nvMaxChildren == toSize);//overflow check d_nv = newBlock; d_nv->d_id = d_inlineNv.d_id; @@ -1276,10 +1285,14 @@ void NodeBuilder<nchild_thresh>::internalCopy(const NodeBuilder<N>& nb) { return; } + bool realloced = false; if(nb.d_nvMaxChildren > d_nvMaxChildren) { + realloced = true; realloc(nb.d_nvMaxChildren); } + Assert(nb.d_nvMaxChildren <= d_nvMaxChildren); + Assert(nb.d_nv->nv_end() - nb.d_nv->nv_begin() <= d_nvMaxChildren, "realloced:%s, d_nvMax:%u, size:%u, nc:%u", realloced ? "true" : "false", d_nvMaxChildren, nb.d_nv->nv_end() - nb.d_nv->nv_begin(), nb.d_nv->getNumChildren()); std::copy(nb.d_nv->nv_begin(), nb.d_nv->nv_end(), d_nv->nv_begin()); |