@@ -272,6 +272,7 @@ int bam_parse_basemod2(const bam1_t *b, hts_base_mod_state *state,
272272 char * cp = (char * )mm + 1 ;
273273 int mod_num = 0 ;
274274 int implicit = 1 ;
275+ int failed = 0 ;
275276 while (* cp ) {
276277 for (; * cp ; cp ++ ) {
277278 // cp should be [ACGTNU][+-]([a-zA-Z]+|[0-9]+)[.?]?(,\d+)*;
@@ -295,7 +296,12 @@ int bam_parse_basemod2(const bam1_t *b, hts_base_mod_state *state,
295296 char * cp_end = NULL ;
296297 int chebi = 0 ;
297298 if (isdigit_c (* cp )) {
298- chebi = strtol (cp , & cp_end , 10 );
299+ chebi = (int )hts_str2uint (cp , & cp_end , 31 , & failed );
300+ if (cp_end == cp || failed ) {
301+ hts_log_error ("%s: malformed MM tag (invalid ChEBI code)" ,
302+ bam_get_qname (b ));
303+ return -1 ;
304+ }
299305 cp = cp_end ;
300306 ms = cp - 1 ;
301307 } else {
@@ -341,8 +347,8 @@ int bam_parse_basemod2(const bam1_t *b, hts_base_mod_state *state,
341347 if (* cp == 0 || * cp == ';' )
342348 break ;
343349
344- delta = strtol ( cp , & cp_end , 10 );
345- if (cp_end == cp ) {
350+ delta = ( long ) hts_str2uint ( cp , & cp_end , 31 , & failed );
351+ if (cp_end == cp || failed ) {
346352 hts_log_error ("%s: Hit end of MM tag. Missing "
347353 "semicolon?" , bam_get_qname (b ));
348354 return -1 ;
@@ -354,11 +360,14 @@ int bam_parse_basemod2(const bam1_t *b, hts_base_mod_state *state,
354360 }
355361 delta = freq [seqi_rc [btype ]] - total_seq ; // remainder
356362 } else {
357- delta = * cp == ','
358- ? strtol (cp + 1 , & cp_end , 10 )
359- : 0 ;
360- if (!cp_end ) {
361- // empty list
363+ if (* cp == ',' ) {
364+ delta = (long )hts_str2uint (cp + 1 , & cp_end , 31 , & failed );
365+ if (cp_end == cp + 1 || failed ) {
366+ hts_log_error ("%s: Failed to parse integer from MM tag" ,
367+ bam_get_qname (b ));
368+ return -1 ;
369+ }
370+ } else {
362371 delta = INT_MAX ;
363372 cp_end = cp ;
364373 }
@@ -494,9 +503,11 @@ int bam_mods_at_next_pos(const bam1_t *b, hts_base_mod_state *state,
494503 ? - state -> MLstride [i ]
495504 : + state -> MLstride [i ];
496505
506+ int failed = 0 ;
497507 if (b -> core .flag & BAM_FREVERSE ) {
498508 // process MM list backwards
499509 char * cp ;
510+ char * tmp ;
500511
501512 if (state -> MMend [i ]- 1 < state -> MM [i ]) {
502513 // Should be impossible to hit if coding is correct
@@ -508,15 +519,19 @@ int bam_mods_at_next_pos(const bam1_t *b, hts_base_mod_state *state,
508519 break ;
509520 state -> MMend [i ] = cp ;
510521 if (cp != state -> MM [i ])
511- state -> MMcount [i ] = strtol ( cp + 1 , NULL , 10 );
522+ state -> MMcount [i ] = ( int ) hts_str2uint ( cp + 1 , & tmp , 31 , & failed );
512523 else
513524 state -> MMcount [i ] = INT_MAX ;
514525 } else {
515526 if (* state -> MM [i ] == ',' )
516- state -> MMcount [i ] = strtol ( state -> MM [i ]+ 1 , & state -> MM [i ], 10 );
527+ state -> MMcount [i ] = ( int ) hts_str2uint ( state -> MM [i ] + 1 , & state -> MM [i ], 31 , & failed );
517528 else
518529 state -> MMcount [i ] = INT_MAX ;
519530 }
531+ if (failed ) {
532+ hts_log_error ("%s: Error parsing unsigned integer from MM tag" , bam_get_qname (b ));
533+ return -1 ;
534+ }
520535
521536 // Multiple mods at the same coords.
522537 for (j = i + 1 ; j < state -> nmods && state -> MM [j ] == MMptr ; j ++ ) {
0 commit comments