From: greensea Date: Tue, 31 Mar 2015 09:28:40 +0000 (+0800) Subject: Fix a segment fault issue in cascade classfier X-Git-Tag: accepted/tizen/6.0/unified/20201030.111113~2542^2 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=52c727f09a6dc8de98c3ecb5b5ecf1d6b19d962f;p=platform%2Fupstream%2Fopencv.git Fix a segment fault issue in cascade classfier work_var_count and sample_count are both 32bit integer, if the product of work_var_count and sample_count is bigger than 2^31, the compiler will treat (work_var_count*sample_count) as a negative number. Force work_var_count as an unsigned 64bit integer to avoid this issue. --- diff --git a/apps/traincascade/boost.cpp b/apps/traincascade/boost.cpp index 5864022..c2e7fb7 100644 --- a/apps/traincascade/boost.cpp +++ b/apps/traincascade/boost.cpp @@ -437,7 +437,7 @@ CvDTreeNode* CvCascadeBoostTrainData::subsample_data( const CvMat* _subsample_id if (is_buf_16u) { unsigned short* udst_idx = (unsigned short*)(buf->data.s + root->buf_idx*get_length_subbuf() + - vi*sample_count + data_root->offset); + (size_t)vi*sample_count + data_root->offset); for( int i = 0; i < num_valid; i++ ) { idx = src_idx[i]; @@ -450,7 +450,7 @@ CvDTreeNode* CvCascadeBoostTrainData::subsample_data( const CvMat* _subsample_id else { int* idst_idx = buf->data.i + root->buf_idx*get_length_subbuf() + - vi*sample_count + root->offset; + (size_t)vi*sample_count + root->offset; for( int i = 0; i < num_valid; i++ ) { idx = src_idx[i]; @@ -467,14 +467,14 @@ CvDTreeNode* CvCascadeBoostTrainData::subsample_data( const CvMat* _subsample_id if (is_buf_16u) { unsigned short* udst = (unsigned short*)(buf->data.s + root->buf_idx*get_length_subbuf() + - (workVarCount-1)*sample_count + root->offset); + (size_t)(workVarCount-1)*sample_count + root->offset); for( int i = 0; i < count; i++ ) udst[i] = (unsigned short)src_lbls[sidx[i]]; } else { int* idst = buf->data.i + root->buf_idx*get_length_subbuf() + - (workVarCount-1)*sample_count + root->offset; + (size_t)(workVarCount-1)*sample_count + root->offset; for( int i = 0; i < count; i++ ) idst[i] = src_lbls[sidx[i]]; } @@ -484,14 +484,14 @@ CvDTreeNode* CvCascadeBoostTrainData::subsample_data( const CvMat* _subsample_id if (is_buf_16u) { unsigned short* sample_idx_dst = (unsigned short*)(buf->data.s + root->buf_idx*get_length_subbuf() + - workVarCount*sample_count + root->offset); + (size_t)workVarCount*sample_count + root->offset); for( int i = 0; i < count; i++ ) sample_idx_dst[i] = (unsigned short)sample_idx_src[sidx[i]]; } else { int* sample_idx_dst = buf->data.i + root->buf_idx*get_length_subbuf() + - workVarCount*sample_count + root->offset; + (size_t)workVarCount*sample_count + root->offset; for( int i = 0; i < count; i++ ) sample_idx_dst[i] = sample_idx_src[sidx[i]]; } @@ -677,9 +677,9 @@ void CvCascadeBoostTrainData::setData( const CvFeatureEvaluator* _featureEvaluat // set sample labels if (is_buf_16u) - udst = (unsigned short*)(buf->data.s + work_var_count*sample_count); + udst = (unsigned short*)(buf->data.s + (size_t)work_var_count*sample_count); else - idst = buf->data.i + work_var_count*sample_count; + idst = buf->data.i + (size_t)work_var_count*sample_count; for (int si = 0; si < sample_count; si++) { @@ -747,11 +747,11 @@ void CvCascadeBoostTrainData::get_ord_var_data( CvDTreeNode* n, int vi, float* o if ( vi < numPrecalcIdx ) { if( !is_buf_16u ) - *sortedIndices = buf->data.i + n->buf_idx*get_length_subbuf() + vi*sample_count + n->offset; + *sortedIndices = buf->data.i + n->buf_idx*get_length_subbuf() + (size_t)vi*sample_count + n->offset; else { const unsigned short* shortIndices = (const unsigned short*)(buf->data.s + n->buf_idx*get_length_subbuf() + - vi*sample_count + n->offset ); + (size_t)vi*sample_count + n->offset ); for( int i = 0; i < nodeSampleCount; i++ ) sortedIndicesBuf[i] = shortIndices[i]; @@ -862,14 +862,14 @@ struct FeatureIdxOnlyPrecalc : ParallelLoopBody { valCachePtr[si] = (*featureEvaluator)( fi, si ); if ( is_buf_16u ) - *(udst + fi*sample_count + si) = (unsigned short)si; + *(udst + (size_t)fi*sample_count + si) = (unsigned short)si; else - *(idst + fi*sample_count + si) = si; + *(idst + (size_t)fi*sample_count + si) = si; } if ( is_buf_16u ) - std::sort(udst + fi*sample_count, udst + (fi + 1)*sample_count, LessThanIdx(valCachePtr) ); + std::sort(udst + (size_t)fi*sample_count, udst + (size_t)(fi + 1)*sample_count, LessThanIdx(valCachePtr) ); else - std::sort(idst + fi*sample_count, idst + (fi + 1)*sample_count, LessThanIdx(valCachePtr) ); + std::sort(idst + (size_t)fi*sample_count, idst + (size_t)(fi + 1)*sample_count, LessThanIdx(valCachePtr) ); } } const CvFeatureEvaluator* featureEvaluator; @@ -898,14 +898,14 @@ struct FeatureValAndIdxPrecalc : ParallelLoopBody { valCache->at(fi,si) = (*featureEvaluator)( fi, si ); if ( is_buf_16u ) - *(udst + fi*sample_count + si) = (unsigned short)si; + *(udst + (size_t)fi*sample_count + si) = (unsigned short)si; else - *(idst + fi*sample_count + si) = si; + *(idst + (size_t)fi*sample_count + si) = si; } if ( is_buf_16u ) - std::sort(udst + fi*sample_count, udst + (fi + 1)*sample_count, LessThanIdx(valCache->ptr(fi)) ); + std::sort(udst + (size_t)fi*sample_count, udst + (size_t)(fi + 1)*sample_count, LessThanIdx(valCache->ptr(fi)) ); else - std::sort(idst + fi*sample_count, idst + (fi + 1)*sample_count, LessThanIdx(valCache->ptr(fi)) ); + std::sort(idst + (size_t)fi*sample_count, idst + (size_t)(fi + 1)*sample_count, LessThanIdx(valCache->ptr(fi)) ); } } const CvFeatureEvaluator* featureEvaluator; @@ -1228,9 +1228,9 @@ void CvCascadeBoostTree::split_node_data( CvDTreeNode* node ) if (data->is_buf_16u) { unsigned short *ldst = (unsigned short *)(buf->data.s + left->buf_idx*length_buf_row + - (workVarCount-1)*scount + left->offset); + (size_t)(workVarCount-1)*scount + left->offset); unsigned short *rdst = (unsigned short *)(buf->data.s + right->buf_idx*length_buf_row + - (workVarCount-1)*scount + right->offset); + (size_t)(workVarCount-1)*scount + right->offset); for( int i = 0; i < n; i++ ) { @@ -1251,9 +1251,9 @@ void CvCascadeBoostTree::split_node_data( CvDTreeNode* node ) else { int *ldst = buf->data.i + left->buf_idx*length_buf_row + - (workVarCount-1)*scount + left->offset; + (size_t)(workVarCount-1)*scount + left->offset; int *rdst = buf->data.i + right->buf_idx*length_buf_row + - (workVarCount-1)*scount + right->offset; + (size_t)(workVarCount-1)*scount + right->offset; for( int i = 0; i < n; i++ ) { @@ -1281,9 +1281,9 @@ void CvCascadeBoostTree::split_node_data( CvDTreeNode* node ) if (data->is_buf_16u) { unsigned short* ldst = (unsigned short*)(buf->data.s + left->buf_idx*length_buf_row + - workVarCount*scount + left->offset); + (size_t)workVarCount*scount + left->offset); unsigned short* rdst = (unsigned short*)(buf->data.s + right->buf_idx*length_buf_row + - workVarCount*scount + right->offset); + (size_t)workVarCount*scount + right->offset); for (int i = 0; i < n; i++) { unsigned short idx = (unsigned short)tempBuf[i]; @@ -1302,9 +1302,9 @@ void CvCascadeBoostTree::split_node_data( CvDTreeNode* node ) else { int* ldst = buf->data.i + left->buf_idx*length_buf_row + - workVarCount*scount + left->offset; + (size_t)workVarCount*scount + left->offset; int* rdst = buf->data.i + right->buf_idx*length_buf_row + - workVarCount*scount + right->offset; + (size_t)workVarCount*scount + right->offset; for (int i = 0; i < n; i++) { int idx = tempBuf[i]; @@ -1473,7 +1473,7 @@ void CvCascadeBoost::update_weights( CvBoostTree* tree ) if (data->is_buf_16u) { unsigned short* labels = (unsigned short*)(buf->data.s + data->data_root->buf_idx*length_buf_row + - data->data_root->offset + (data->work_var_count-1)*data->sample_count); + data->data_root->offset + (size_t)(data->work_var_count-1)*data->sample_count); for( int i = 0; i < n; i++ ) { // save original categorical responses {0,1}, convert them to {-1,1} @@ -1491,7 +1491,7 @@ void CvCascadeBoost::update_weights( CvBoostTree* tree ) else { int* labels = buf->data.i + data->data_root->buf_idx*length_buf_row + - data->data_root->offset + (data->work_var_count-1)*data->sample_count; + data->data_root->offset + (size_t)(data->work_var_count-1)*data->sample_count; for( int i = 0; i < n; i++ ) { diff --git a/apps/traincascade/old_ml_boost.cpp b/apps/traincascade/old_ml_boost.cpp index be4cd81..fae3d60 100644 --- a/apps/traincascade/old_ml_boost.cpp +++ b/apps/traincascade/old_ml_boost.cpp @@ -1200,7 +1200,7 @@ CvBoost::update_weights( CvBoostTree* tree ) if (data->is_buf_16u) { unsigned short* labels = (unsigned short*)(dtree_data_buf->data.s + data->data_root->buf_idx*length_buf_row + - data->data_root->offset + (data->work_var_count-1)*data->sample_count); + data->data_root->offset + (size_t)(data->work_var_count-1)*data->sample_count); for( i = 0; i < n; i++ ) { // save original categorical responses {0,1}, convert them to {-1,1} @@ -1218,7 +1218,7 @@ CvBoost::update_weights( CvBoostTree* tree ) else { int* labels = dtree_data_buf->data.i + data->data_root->buf_idx*length_buf_row + - data->data_root->offset + (data->work_var_count-1)*data->sample_count; + data->data_root->offset + (size_t)(data->work_var_count-1)*data->sample_count; for( i = 0; i < n; i++ ) { diff --git a/apps/traincascade/old_ml_tree.cpp b/apps/traincascade/old_ml_tree.cpp index b7e346c..d7c6511 100644 --- a/apps/traincascade/old_ml_tree.cpp +++ b/apps/traincascade/old_ml_tree.cpp @@ -424,9 +424,9 @@ void CvDTreeTrainData::set_data( const CvMat* _train_data, int _tflag, int* c_map; if (is_buf_16u) - udst = (unsigned short*)(buf->data.s + vi*sample_count); + udst = (unsigned short*)(buf->data.s + (size_t)vi*sample_count); else - idst = buf->data.i + vi*sample_count; + idst = buf->data.i + (size_t)vi*sample_count; // copy data for( i = 0; i < sample_count; i++ ) @@ -540,9 +540,9 @@ void CvDTreeTrainData::set_data( const CvMat* _train_data, int _tflag, else if( ci < 0 ) // process ordered variable { if (is_buf_16u) - udst = (unsigned short*)(buf->data.s + vi*sample_count); + udst = (unsigned short*)(buf->data.s + (size_t)vi*sample_count); else - idst = buf->data.i + vi*sample_count; + idst = buf->data.i + (size_t)vi*sample_count; for( i = 0; i < sample_count; i++ ) { @@ -583,9 +583,9 @@ void CvDTreeTrainData::set_data( const CvMat* _train_data, int _tflag, // set sample labels if (is_buf_16u) - udst = (unsigned short*)(buf->data.s + work_var_count*sample_count); + udst = (unsigned short*)(buf->data.s + (size_t)work_var_count*sample_count); else - idst = buf->data.i + work_var_count*sample_count; + idst = buf->data.i + (size_t)work_var_count*sample_count; for (i = 0; i < sample_count; i++) { @@ -602,7 +602,7 @@ void CvDTreeTrainData::set_data( const CvMat* _train_data, int _tflag, if (is_buf_16u) { - usdst = (unsigned short*)(buf->data.s + (get_work_var_count()-1)*sample_count); + usdst = (unsigned short*)(buf->data.s + (size_t)(get_work_var_count()-1)*sample_count); for( i = vi = 0; i < sample_count; i++ ) { usdst[i] = (unsigned short)vi++; @@ -619,7 +619,7 @@ void CvDTreeTrainData::set_data( const CvMat* _train_data, int _tflag, } else { - idst2 = buf->data.i + (get_work_var_count()-1)*sample_count; + idst2 = buf->data.i + (size_t)(get_work_var_count()-1)*sample_count; for( i = vi = 0; i < sample_count; i++ ) { idst2[i] = vi++; @@ -785,7 +785,7 @@ CvDTreeNode* CvDTreeTrainData::subsample_data( const CvMat* _subsample_idx ) if (is_buf_16u) { unsigned short* udst = (unsigned short*)(buf->data.s + root->buf_idx*get_length_subbuf() + - vi*sample_count + root->offset); + (size_t)vi*sample_count + root->offset); for( i = 0; i < count; i++ ) { int val = src[sidx[i]]; @@ -796,7 +796,7 @@ CvDTreeNode* CvDTreeTrainData::subsample_data( const CvMat* _subsample_idx ) else { int* idst = buf->data.i + root->buf_idx*get_length_subbuf() + - vi*sample_count + root->offset; + (size_t)vi*sample_count + root->offset; for( i = 0; i < count; i++ ) { int val = src[sidx[i]]; @@ -822,7 +822,7 @@ CvDTreeNode* CvDTreeTrainData::subsample_data( const CvMat* _subsample_idx ) if (is_buf_16u) { unsigned short* udst_idx = (unsigned short*)(buf->data.s + root->buf_idx*get_length_subbuf() + - vi*sample_count + data_root->offset); + (size_t)vi*sample_count + data_root->offset); for( i = 0; i < num_valid; i++ ) { idx = src_idx[i]; @@ -846,7 +846,7 @@ CvDTreeNode* CvDTreeTrainData::subsample_data( const CvMat* _subsample_idx ) else { int* idst_idx = buf->data.i + root->buf_idx*get_length_subbuf() + - vi*sample_count + root->offset; + (size_t)vi*sample_count + root->offset; for( i = 0; i < num_valid; i++ ) { idx = src_idx[i]; @@ -874,14 +874,14 @@ CvDTreeNode* CvDTreeTrainData::subsample_data( const CvMat* _subsample_idx ) if (is_buf_16u) { unsigned short* sample_idx_dst = (unsigned short*)(buf->data.s + root->buf_idx*get_length_subbuf() + - workVarCount*sample_count + root->offset); + (size_t)workVarCount*sample_count + root->offset); for (i = 0; i < count; i++) sample_idx_dst[i] = (unsigned short)sample_idx_src[sidx[i]]; } else { int* sample_idx_dst = buf->data.i + root->buf_idx*get_length_subbuf() + - workVarCount*sample_count + root->offset; + (size_t)workVarCount*sample_count + root->offset; for (i = 0; i < count; i++) sample_idx_dst[i] = sample_idx_src[sidx[i]]; } @@ -1192,10 +1192,10 @@ void CvDTreeTrainData::get_ord_var_data( CvDTreeNode* n, int vi, float* ord_valu if( !is_buf_16u ) *sorted_indices = buf->data.i + n->buf_idx*get_length_subbuf() + - vi*sample_count + n->offset; + (size_t)vi*sample_count + n->offset; else { const unsigned short* short_indices = (const unsigned short*)(buf->data.s + n->buf_idx*get_length_subbuf() + - vi*sample_count + n->offset ); + (size_t)vi*sample_count + n->offset ); for( int i = 0; i < node_sample_count; i++ ) sorted_indices_buf[i] = short_indices[i]; *sorted_indices = sorted_indices_buf; @@ -1266,10 +1266,10 @@ const int* CvDTreeTrainData::get_cat_var_data( CvDTreeNode* n, int vi, int* cat_ const int* cat_values = 0; if( !is_buf_16u ) cat_values = buf->data.i + n->buf_idx*get_length_subbuf() + - vi*sample_count + n->offset; + (size_t)vi*sample_count + n->offset; else { const unsigned short* short_values = (const unsigned short*)(buf->data.s + n->buf_idx*get_length_subbuf() + - vi*sample_count + n->offset); + (size_t)vi*sample_count + n->offset); for( int i = 0; i < n->sample_count; i++ ) cat_values_buf[i] = short_values[i]; cat_values = cat_values_buf;