diff --git a/cram/cram_decode.c b/cram/cram_decode.c index 2b2ad6029..a622e42ab 100644 --- a/cram/cram_decode.c +++ b/cram/cram_decode.c @@ -3247,6 +3247,10 @@ cram_slice *cram_next_slice(cram_fd *fd, cram_container **cp) { if (fd->ooc) break; +// printf("%p %d:%ld-%ld vs %d:%ld-%ld\n", fd, +// c_next->ref_seq_id, c_next->ref_seq_start, c_next->ref_seq_start+c_next->ref_seq_span-1, +// fd->range.refid, fd->range.start, fd->range.end); + /* Skip containers not yet spanning our range */ if (fd->range.refid != -2 && c_next->ref_seq_id != -2) { // ref_id beyond end of range; bail out diff --git a/cram/cram_encode.c b/cram/cram_encode.c index f4a75a67c..6fe797a64 100644 --- a/cram/cram_encode.c +++ b/cram/cram_encode.c @@ -3691,7 +3691,8 @@ static int process_one_read(cram_fd *fd, cram_container *c, return -1; } fake_qual = spos; - cr->aend = no_ref ? apos : MIN(apos, c->ref_end); + // Protect against negative length refs (fuzz 382922241) + cr->aend = no_ref ? apos : MIN(apos, MAX(0, c->ref_end)); if (cram_stats_add(c->stats[DS_FN], cr->nfeature) < 0) goto block_err; diff --git a/cram/cram_io.c b/cram/cram_io.c index 7009887ad..35dbb99c8 100644 --- a/cram/cram_io.c +++ b/cram/cram_io.c @@ -2790,9 +2790,13 @@ static int refs_from_header(cram_fd *fd) { if ((tag = sam_hrecs_find_key(ty, "M5", NULL))) r->ref_id[j]->fn = string_dup(r->pool, tag->str+3); - if ((tag = sam_hrecs_find_key(ty, "LN", NULL))) + if ((tag = sam_hrecs_find_key(ty, "LN", NULL))) { // LN tag used when constructing consensus reference r->ref_id[j]->LN_length = strtoll(tag->str+3, NULL, 0); + // See fuzz 382922241 + if (r->ref_id[j]->LN_length < 0) + r->ref_id[j]->LN_length = 0; + } } k = kh_put(refs, r->h_meta, r->ref_id[j]->name, &n); @@ -5818,6 +5822,8 @@ int cram_set_voption(cram_fd *fd, enum hts_fmt_option opt, va_list args) { case CRAM_OPT_RANGE: { int r = cram_seek_to_refpos(fd, va_arg(args, cram_range *)); pthread_mutex_lock(&fd->range_lock); +// printf("opt range noseek to %p %d:%ld-%ld\n", +// fd, fd->range.refid, fd->range.start, fd->range.end); if (fd->range.refid != -2) fd->required_fields |= SAM_POS; pthread_mutex_unlock(&fd->range_lock);