Skip to content
This repository has been archived by the owner on Dec 16, 2022. It is now read-only.

Commit

Permalink
Fix bug in validation of vector lengths when setting individual fields
Browse files Browse the repository at this point in the history
Previous validation routine would incorrectly allow nested vectors
whose first dimension was greater than but divisible by the number of
samples. Now validation of vector<vector> is separated from validation
of flattened vectors.
  • Loading branch information
droazen authored and jmthibault79 committed Oct 1, 2014
1 parent 4c011ec commit e8d3d38
Show file tree
Hide file tree
Showing 2 changed files with 15 additions and 5 deletions.
17 changes: 13 additions & 4 deletions gamgee/variant_builder.cpp
Expand Up @@ -471,7 +471,7 @@ VariantBuilder& VariantBuilder::bulk_set_individual_field(const FIELD_ID_TYPE& f
const auto field_idx = field_index(field_id);
if ( m_enable_validation ) {
validate_individual_field(field_idx, provided_type);
validate_multi_sample_indiv_vector_length(field_values.size());
validate_multi_sample_vector_length(field_values);
}
// Need to use std::forward() here so that we can handle both the move and the copy use cases
fields_of_type[m_indiv_field_lookup_table[field_idx]].set_entire_field(std::forward<BULK_FIELD_VALUES_TYPE>(field_values));
Expand Down Expand Up @@ -569,12 +569,21 @@ void VariantBuilder::validate_individual_field_existence(const int32_t field_ind
}
}

inline void VariantBuilder::validate_multi_sample_indiv_vector_length(const uint32_t length) const {
if ( length == 0 || length % uint32_t(bcf_hdr_nsamples(m_header.get())) != 0 ) {
throw invalid_argument(string{"Number of elements in vector for individual field ("} + to_string(length) + ") not divisible by number of samples (" + to_string(uint32_t(bcf_hdr_nsamples(m_header.get()))) + ")");
template<class ELEMENT_TYPE>
inline void VariantBuilder::validate_multi_sample_vector_length(const std::vector<std::vector<ELEMENT_TYPE>>& vec) const {
const auto num_samples = uint32_t(bcf_hdr_nsamples(m_header.get()));
if ( vec.size() != num_samples ) {
throw invalid_argument(string{"Number of elements in vector of vectors for individual field ("} + to_string(vec.size()) + ") not equal to the number of samples (" + to_string(num_samples) + ")");
}
}

template<class ELEMENT_TYPE>
inline void VariantBuilder::validate_multi_sample_vector_length(const std::vector<ELEMENT_TYPE>& vec) const {
const auto num_samples = uint32_t(bcf_hdr_nsamples(m_header.get()));
if ( vec.size() < num_samples || vec.size() % num_samples != 0 ) {
throw invalid_argument(string{"Number of elements in flattened vector for individual field ("} + to_string(vec.size()) + ") not divisible by number of samples (" + to_string(num_samples) + ")");
}
}

void VariantBuilder::pre_build_validation() const {
if ( (m_starting_variant_body == nullptr && (m_ref_allele.missing() || m_ref_allele.encoded_length() == 0)) ||
Expand Down
3 changes: 2 additions & 1 deletion gamgee/variant_builder.h
Expand Up @@ -188,7 +188,8 @@ class VariantBuilder {
void validate_individual_field(const int32_t field_index, const uint32_t provided_type) const;
void validate_individual_field(const int32_t field_index, const int32_t sample_index, const uint32_t provided_type) const;
inline void validate_individual_field_existence(const int32_t field_index) const;
inline void validate_multi_sample_indiv_vector_length(const uint32_t length) const;
template<class ELEMENT_TYPE> inline void validate_multi_sample_vector_length(const std::vector<std::vector<ELEMENT_TYPE>>& vec) const;
template<class ELEMENT_TYPE> inline void validate_multi_sample_vector_length(const std::vector<ELEMENT_TYPE>& vec) const;
void pre_build_validation() const;
void post_build_validation(const std::shared_ptr<bcf1_t>& new_variant_body) const;

Expand Down

0 comments on commit e8d3d38

Please sign in to comment.