Skip to content

Commit 3addbc9

Browse files
committed
add tests; implement bounds check for proxy
1 parent 84c885a commit 3addbc9

File tree

3 files changed

+36
-36
lines changed

3 files changed

+36
-36
lines changed

inst/include/Rcpp/vector/traits.h

Lines changed: 20 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -45,44 +45,21 @@ namespace traits{
4545
inline iterator get() const { return start; }
4646
inline const_iterator get_const() const { return start; }
4747

48-
inline proxy ref() {
49-
#ifndef RCPP_NO_BOUNDS_CHECK
50-
check_index(0) ;
51-
#endif
52-
return start[0];
53-
}
54-
55-
inline proxy ref() const {
56-
#ifndef RCPP_NO_BOUNDS_CHECK
57-
check_index(0) ;
58-
#endif
59-
return start[0] ;
60-
}
61-
62-
inline proxy ref(R_xlen_t i) {
63-
#ifndef RCPP_NO_BOUNDS_CHECK
64-
check_index(i) ;
65-
#endif
66-
return start[i] ;
67-
}
48+
inline proxy ref() { check_index(0); return start[0] ;}
49+
inline proxy ref(R_xlen_t i) { check_index(i); return start[i] ; }
6850

69-
70-
inline proxy ref(R_xlen_t i) const {
71-
#ifndef RCPP_NO_BOUNDS_CHECK
72-
check_index(i) ;
73-
#endif
74-
return start[i] ;
75-
}
51+
inline proxy ref() const { check_index(0); return start[0] ;}
52+
inline proxy ref(R_xlen_t i) const { check_index(i); return start[i] ; }
7653

7754
private:
7855

79-
#ifndef RCPP_NO_BOUNDS_CHECK
8056
void check_index(R_xlen_t i) const {
57+
#ifndef RCPP_NO_BOUNDS_CHECK
8158
if (i >= size) {
8259
stop("subscript out of bounds (index %s >= vector size %s)", i, size);
8360
}
84-
}
8561
#endif
62+
}
8663

8764
iterator start ;
8865
R_xlen_t size ;
@@ -102,18 +79,25 @@ namespace traits{
10279
void update( const VECTOR& v ){
10380
p = const_cast<VECTOR*>(&v) ;
10481
}
105-
inline iterator get() const { return iterator( proxy(*p, 0 ) ) ;}
106-
// inline const_iterator get_const() const { return const_iterator( *p ) ;}
107-
inline const_iterator get_const() const { return const_iterator( const_proxy(*p, 0) ) ; }
82+
inline iterator get() const { check_index(0); return iterator( proxy(*p, 0 ) ) ;}
83+
inline const_iterator get_const() const { check_index(0); return const_iterator( const_proxy(*p, 0) ) ; }
10884

109-
inline proxy ref() { return proxy(*p,0) ; }
110-
inline proxy ref(R_xlen_t i) { return proxy(*p,i);}
85+
inline proxy ref() { check_index(0); return proxy(*p,0) ; }
86+
inline proxy ref(R_xlen_t i) { check_index(i); return proxy(*p,i);}
11187

112-
inline const_proxy ref() const { return const_proxy(*p,0) ; }
113-
inline const_proxy ref(R_xlen_t i) const { return const_proxy(*p,i);}
88+
inline const_proxy ref() const { check_index(0); return const_proxy(*p,0) ; }
89+
inline const_proxy ref(R_xlen_t i) const { check_index(i); return const_proxy(*p,i);}
11490

11591
private:
11692
VECTOR* p ;
93+
94+
void check_index(R_xlen_t i) const {
95+
#ifndef RCPP_NO_BOUNDS_CHECK
96+
if (i >= size) {
97+
stop("subscript out of bounds (index %s >= vector size %s)", i, size);
98+
}
99+
#endif
100+
}
117101
} ;
118102

119103
// regular types for INTSXP, REALSXP, ...

inst/tinytest/cpp/Vector.cpp

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -886,3 +886,15 @@ bool CharacterVector_test_equality_crosspolicy(CharacterVector x, Vector<STRSXP,
886886

887887
return std::equal(x.begin(), x.end(), y.begin());
888888
}
889+
890+
// [[Rcpp::export]]
891+
double NumericVector_test_out_of_bounds_read() {
892+
NumericVector v(3);
893+
return v[5];
894+
}
895+
896+
// [[Rcpp::export]]
897+
SEXP CharacterVector_test_out_of_bounds_read() {
898+
CharacterVector v(3);
899+
return v[5];
900+
}

inst/tinytest/test_vector.R

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -694,3 +694,7 @@ expect_equal(data, data2)
694694
# test.CharacterVector_test_equality <- function(){
695695
expect_true( !CharacterVector_test_equality("foo", "bar") )
696696
expect_true( !CharacterVector_test_equality_crosspolicy("foo", "bar") )
697+
698+
699+
expect_error(NumericVector_test_out_of_bounds_read())
700+
expect_error(CharacterVector_test_out_of_bounds_read())

0 commit comments

Comments
 (0)