@@ -597,7 +597,6 @@ heapframe *P = NULL;
597597
598598heapframe * frames_top ; /* End of frames vector */
599599heapframe * assert_accept_frame = NULL ; /* For passing back a frame with captures */
600- PCRE2_SIZE heapframes_size ; /* Usable size of frames vector */
601600PCRE2_SIZE frame_copy_size ; /* Amount to copy when creating a new frame */
602601
603602/* Local variables that do not need to be preserved over calls to RRMATCH(). */
@@ -635,13 +634,10 @@ copied when a new frame is created. */
635634
636635frame_copy_size = frame_size - offsetof(heapframe , eptr );
637636
638- /* Set up the first frame and the end of the frames vector. We set the local
639- heapframes_size to the usuable amount of the vector, that is, a whole number of
640- frames. */
637+ /* Set up the first frame and the end of the frames vector. */
641638
642639F = match_data -> heapframes ;
643- heapframes_size = (match_data -> heapframes_size / frame_size ) * frame_size ;
644- frames_top = (heapframe * )((char * )F + heapframes_size );
640+ frames_top = (heapframe * )((char * )F + match_data -> heapframes_size );
645641
646642Frdepth = 0 ; /* "Recursion" depth */
647643Fcapture_last = 0 ; /* Number of most recent capture */
@@ -662,10 +658,11 @@ backtracking point. */
662658doubling the size, but constrained by the heap limit (which is in KiB). */
663659
664660N = (heapframe * )((char * )F + frame_size );
665- if (N >= frames_top )
661+ if (( heapframe * )(( char * ) N + frame_size ) >= frames_top )
666662 {
667663 heapframe * new ;
668664 PCRE2_SIZE newsize ;
665+ PCRE2_SIZE usedsize = (char * )N - (char * )(match_data -> heapframes );
669666
670667 if (match_data -> heapframes_size >= PCRE2_SIZE_MAX / 2 )
671668 {
@@ -679,7 +676,8 @@ if (N >= frames_top)
679676 if (newsize / 1024 >= mb -> heap_limit )
680677 {
681678 PCRE2_SIZE old_size = match_data -> heapframes_size / 1024 ;
682- if (mb -> heap_limit <= old_size ) return PCRE2_ERROR_HEAPLIMIT ;
679+ if (mb -> heap_limit <= old_size )
680+ return PCRE2_ERROR_HEAPLIMIT ;
683681 else
684682 {
685683 PCRE2_SIZE max_delta = 1024 * (mb -> heap_limit - old_size );
@@ -689,19 +687,21 @@ if (N >= frames_top)
689687 }
690688 }
691689
690+ /* With a heap limit set, the permitted additional size may not be enough for
691+ another frame, so do a final check. */
692+
693+ if (newsize - usedsize < frame_size ) return PCRE2_ERROR_HEAPLIMIT ;
692694 new = match_data -> memctl .malloc (newsize , match_data -> memctl .memory_data );
693695 if (new == NULL ) return PCRE2_ERROR_NOMEMORY ;
694- memcpy (new , match_data -> heapframes , heapframes_size );
696+ memcpy (new , match_data -> heapframes , usedsize );
695697
696- F = (heapframe * )((char * )new + (( char * ) F - ( char * ) match_data -> heapframes ) );
697- N = (heapframe * )((char * )F + frame_size );
698+ N = (heapframe * )((char * )new + usedsize );
699+ F = (heapframe * )((char * )N - frame_size );
698700
699701 match_data -> memctl .free (match_data -> heapframes , match_data -> memctl .memory_data );
700702 match_data -> heapframes = new ;
701703 match_data -> heapframes_size = newsize ;
702-
703- heapframes_size = (newsize / frame_size ) * frame_size ;
704- frames_top = (heapframe * )((char * )new + heapframes_size );
704+ frames_top = (heapframe * )((char * )new + newsize );
705705 }
706706
707707#ifdef DEBUG_SHOW_RMATCH
@@ -6842,8 +6842,7 @@ mb->match_limit_depth = (mcontext->depth_limit < re->limit_depth)?
68426842/* If a pattern has very many capturing parentheses, the frame size may be very
68436843large. Set the initial frame vector size to ensure that there are at least 10
68446844available frames, but enforce a minimum of START_FRAMES_SIZE. If this is
6845- greater than the heap limit, get as large a vector as possible. Always round
6846- the size to a multiple of the frame size. */
6845+ greater than the heap limit, get as large a vector as possible. */
68476846
68486847heapframes_size = frame_size * 10 ;
68496848if (heapframes_size < START_FRAMES_SIZE ) heapframes_size = START_FRAMES_SIZE ;
@@ -7301,7 +7300,6 @@ for(;;)
73017300 mb -> match_call_count = 0 ;
73027301 mb -> end_offset_top = 0 ;
73037302 mb -> skip_arg_count = 0 ;
7304-
73057303 rc = match (start_match , mb -> start_code , re -> top_bracket , frame_size ,
73067304 match_data , mb );
73077305
0 commit comments