@@ -403,21 +403,22 @@ Perl_grok_bin_oct_hex(pTHX_ const char *start,
403403 cBOOL (input_flags & PERL_SCAN_ALLOW_UNDERSCORES );
404404 const char * s = start ;
405405 const char * s0 = s ; /* Where the significant digits start */
406- STRLEN len = * len_p ;
406+ const char * e = start + * len_p ;
407407
408408 if (!(input_flags & PERL_SCAN_DISALLOW_PREFIX )) {
409409
410410 /* strip off leading b or 0b; x or 0x.
411411 for compatibility silently suffer "b" and "0b" as valid binary; "x"
412412 and "0x" as valid hex numbers. */
413- if (len >= 1 ) {
413+ if (e - s > 1 ) {
414414 if (isALPHA_FOLD_EQ (s0 [0 ], prefix )) {
415415 s0 ++ ;
416- len -- ;
417416 }
418- else if (len >= 2 && s0 [0 ] == '0' && (isALPHA_FOLD_EQ (s0 [1 ], prefix ))) {
417+ else if ( e - s > 2
418+ && s0 [0 ] == '0'
419+ && (isALPHA_FOLD_EQ (s0 [1 ], prefix )))
420+ {
419421 s0 += 2 ;
420- len -= 2 ;
421422 }
422423 }
423424 }
@@ -427,7 +428,7 @@ Perl_grok_bin_oct_hex(pTHX_ const char *start,
427428
428429 /* Unroll the loop so that the first 8 digits are branchless except for the
429430 * switch. A ninth hex one overflows a 32 bit word. */
430- switch (len ) {
431+ switch (e - s ) {
431432 case 0 :
432433 return 0 ;
433434 default :
@@ -468,12 +469,12 @@ Perl_grok_bin_oct_hex(pTHX_ const char *start,
468469 case 1 :
469470 if (UNLIKELY (! generic_isCC_ (* s , class_bit ))) break ;
470471 value = (value << shift ) | XDIGIT_VALUE (* s );
472+ s ++ ;
471473
472- if (LIKELY (len <= 8 )) {
474+ if (LIKELY (s >= e )) {
473475 return value ;
474476 }
475477
476- s ++ ;
477478 break ;
478479 }
479480
@@ -483,15 +484,14 @@ Perl_grok_bin_oct_hex(pTHX_ const char *start,
483484 /* In overflows, this keeps track of how much to multiply the overflowed NV
484485 * by as we continue to parse the remaining digits */
485486 NV factor = shift << bytes_so_far ;
486- len -= bytes_so_far ;
487487
488488 bool overflowed = FALSE;
489489 NV value_nv = 0 ;
490490 const PERL_UINT_FAST8_T base = 1 << shift ; /* 2, 8, or 16 */
491491 const UV max_div = UV_MAX / base ; /* Value above which, the next digit
492492 processed would overflow */
493493
494- for (; len -- ; s ++ ) {
494+ for (; s < e ; s ++ ) {
495495 if (generic_isCC_ (* s , class_bit )) {
496496 /* Write it in this wonky order with a goto to attempt to get the
497497 compiler to make the common case integer-only loop pretty tight.
@@ -540,7 +540,7 @@ Perl_grok_bin_oct_hex(pTHX_ const char *start,
540540 }
541541
542542 if ( * s == '_'
543- && len
543+ && s < e - 1
544544 && allow_underscores
545545 && generic_isCC_ (s [1 ], class_bit )
546546
@@ -550,7 +550,6 @@ Perl_grok_bin_oct_hex(pTHX_ const char *start,
550550 || UNLIKELY ((input_flags & PERL_SCAN_ALLOW_MEDIAL_UNDERSCORES )
551551 != PERL_SCAN_ALLOW_MEDIAL_UNDERSCORES )))
552552 {
553- -- len ;
554553 ++ s ;
555554 goto redo ;
556555 }
0 commit comments