Skip to content

Commit

Permalink
Catch arrays of BCF_BT_NULL in bcf_record_check()
Browse files Browse the repository at this point in the history
Adds a check for INFO/FORMAT values with type 0 ("A MISSING value
without an explicit type provided") and number of elements > 0.

Normally type = 0 and number = 0 is used for a completely
missing INFO/FORMAT value.  In theory you could use number > 0
to make an array of missing values (at least the specification
doesn't explicitly disallow it), however trying to do so results
in bcf_fmt_array() reporting "Unexpected type 0" and calling
exit(1).  HTSJDK also appears to reject this encoding, and
nothing appears to write it, so it seems reasonable to say that
it's not valid.

The check for this encoding is added to bcf_record_check()
so it's caught well before the data gets near bcf_fmt_array().
It also avoids problems with bcf_type_shift[], which cannot
report the correct size of type = 0 encodings (it would need
to multiply by 0, which isn't stricty possible with a shift).

Credit to OSS-Fuzz
Fixes oss-fuzz 49091
  • Loading branch information
daviesrob authored and whitwham committed Aug 2, 2022
1 parent 3e28921 commit ad80f8e
Showing 1 changed file with 4 additions and 2 deletions.
6 changes: 4 additions & 2 deletions vcf.c
Original file line number Diff line number Diff line change
Expand Up @@ -1599,7 +1599,8 @@ static int bcf_record_check(const bcf_hdr_t *hdr, bcf1_t *rec) {
err |= BCF_ERR_TAG_UNDEF;
}
if (bcf_dec_size_safe(ptr, end, &ptr, &num, &type) != 0) goto bad_shared;
if (((1 << type) & is_valid_type) == 0) {
if (((1 << type) & is_valid_type) == 0
|| (type == BCF_BT_NULL && num > 0)) {
if (!reports++ || hts_verbose >= HTS_LOG_DEBUG)
hts_log_warning("Bad BCF record at %s:%"PRIhts_pos": Invalid %s type %d (%s)", bcf_seqname_safe(hdr,rec), rec->pos+1, "INFO", type, get_type_name(type));
err |= BCF_ERR_TAG_INVALID;
Expand All @@ -1623,7 +1624,8 @@ static int bcf_record_check(const bcf_hdr_t *hdr, bcf1_t *rec) {
err |= BCF_ERR_TAG_UNDEF;
}
if (bcf_dec_size_safe(ptr, end, &ptr, &num, &type) != 0) goto bad_indiv;
if (((1 << type) & is_valid_type) == 0) {
if (((1 << type) & is_valid_type) == 0
|| (type == BCF_BT_NULL && num > 0)) {
bcf_record_check_err(hdr, rec, "type", &reports, type);
err |= BCF_ERR_TAG_INVALID;
}
Expand Down

0 comments on commit ad80f8e

Please sign in to comment.