diff --git a/infer/models/cpp/include/infer_model/vector_bufferoverrun.h b/infer/models/cpp/include/infer_model/vector_bufferoverrun.h index ac4213b3b..81acf5782 100644 --- a/infer/models/cpp/include/infer_model/vector_bufferoverrun.h +++ b/infer/models/cpp/include/infer_model/vector_bufferoverrun.h @@ -86,9 +86,9 @@ class vector { void* _ignore1; void* _ignore2; - void access_at(size_type index) { + void access_at(size_type index) const { _Tp* dummy_array = (_Tp*) malloc(sizeof(value_type) * infer_size); - auto dummy_value = dummy_array[index]; + __infer_deref_first_arg(&dummy_array[index]); free(dummy_array); } @@ -106,7 +106,7 @@ class vector { template void allocate_iter(Iter begin, Iter end) { - allocate(end - begin); + allocate(distance(begin, end)); } /* std::vector implementation */ @@ -482,14 +482,12 @@ template inline typename vector<_Tp, _Allocator>::iterator vector<_Tp, _Allocator>::erase(const_iterator __position) { infer_size--; - return __position; } template typename vector<_Tp, _Allocator>::iterator vector<_Tp, _Allocator>::erase( const_iterator __first, const_iterator __last) { - infer_size -= __last - __first; - return __first; + infer_size -= distance(__first, __last); } template @@ -526,7 +524,7 @@ typename enable_if::insert(const_iterator __position, _ForwardIterator __first, _ForwardIterator __last) { - infer_size += __last - __first; + infer_size += distance(__first, __last); } template diff --git a/infer/tests/codetoanalyze/cpp/bufferoverrun/issues.exp b/infer/tests/codetoanalyze/cpp/bufferoverrun/issues.exp index abfe69d96..7ab2111f8 100644 --- a/infer/tests/codetoanalyze/cpp/bufferoverrun/issues.exp +++ b/infer/tests/codetoanalyze/cpp/bufferoverrun/issues.exp @@ -2,4 +2,6 @@ codetoanalyze/cpp/bufferoverrun/function_call.cpp, call_by_ref_good_FP, 4, BUFFE codetoanalyze/cpp/bufferoverrun/simple_vector.cpp, instantiate_my_vector_oob_Ok, 3, BUFFER_OVERRUN, [Offset: [-oo, +oo] Size: [0, +oo] @ codetoanalyze/cpp/bufferoverrun/simple_vector.cpp:21:23 by call `my_vector_oob_Bad()` ] codetoanalyze/cpp/bufferoverrun/simple_vector.cpp, my_vector_oob_Bad, 2, BUFFER_OVERRUN, [Offset: [s$6, s$7] Size: [s$6, s$7] @ codetoanalyze/cpp/bufferoverrun/simple_vector.cpp:21:23 by call `int_vector_access_at()` ] codetoanalyze/cpp/bufferoverrun/trivial.cpp, trivial, 2, BUFFER_OVERRUN, [Offset: [10, 10] Size: [10, 10]] -codetoanalyze/cpp/bufferoverrun/vector.cpp, out_of_bound_Bad, 2, BUFFER_OVERRUN, [Offset: [s$14, s$15] Size: [s$14, s$15] @ INFER_MODEL/cpp/include/infer_model/vector_bufferoverrun.h:91:24 by call `std::vector>_operator[]()` ] +codetoanalyze/cpp/bufferoverrun/vector.cpp, just_test_model_FP, 11, BUFFER_OVERRUN, [Offset: [0, 0] Size: [0, +oo] @ INFER_MODEL/cpp/include/infer_model/vector_bufferoverrun.h:91:5 by call `std::vector>_operator[]()` ] +codetoanalyze/cpp/bufferoverrun/vector.cpp, just_test_model_FP, 18, BUFFER_OVERRUN, [Offset: [1, 1] Size: [0, +oo] @ INFER_MODEL/cpp/include/infer_model/vector_bufferoverrun.h:91:5 by call `std::vector>_at()` ] +codetoanalyze/cpp/bufferoverrun/vector.cpp, out_of_bound_Bad, 2, BUFFER_OVERRUN, [Offset: [s$14, s$15] Size: [s$14, s$15] @ INFER_MODEL/cpp/include/infer_model/vector_bufferoverrun.h:91:5 by call `std::vector>_operator[]()` ] diff --git a/infer/tests/codetoanalyze/cpp/bufferoverrun/vector.cpp b/infer/tests/codetoanalyze/cpp/bufferoverrun/vector.cpp index 28730d226..364fc6ef1 100644 --- a/infer/tests/codetoanalyze/cpp/bufferoverrun/vector.cpp +++ b/infer/tests/codetoanalyze/cpp/bufferoverrun/vector.cpp @@ -7,8 +7,42 @@ * of patent rights can be found in the PATENTS file in the same directory. */ #include +#include void out_of_bound_Bad(std::vector v) { unsigned int n = v.size(); v[n] = 1; } + +struct Int_no_copy { + Int_no_copy(Int_no_copy&) = delete; + Int_no_copy(const Int_no_copy&) = delete; + Int_no_copy(volatile Int_no_copy&) = delete; + Int_no_copy(const volatile Int_no_copy&) = delete; + Int_no_copy(int i) : _i(i) {} + int get_int() { return _i; } + + private: + int _i; +}; + +void just_test_model_FP(void) { + std::vector v; + v.push_back(Int_no_copy(0)); + v.erase(v.cbegin()); + v.erase(v.cbegin(), v.cend()); + const Int_no_copy ci(1); + const Int_no_copy& cr = ci; + v.insert(v.cbegin(), cr); + v.insert(v.cbegin(), std::move(Int_no_copy(2))); + v.emplace(v.cbegin(), 3); + v.insert(v.cbegin(), 42, cr); + int x = v[0].get_int(); + std::list l; + std::vector v2(l.begin(), l.end()); + v2.insert(v2.cbegin(), l.begin(), l.end()); + v2.assign(l.begin(), l.end()); + const std::vector v3{1, 2, 3}; + int y = v3[0]; + int z = v3.at(1); +}