From: pclink@qld.tne.oz.AU (Rick)
Subject: Broken intervals in regex.c: bugfix
Organization: GNUs Not Usenet
Distribution: gnu
Date: Tue, 1 Sep 1992 01:55:27 GMT

regex.c doesn't work correctly with intervals.  The compiled regex
contains counters to track how many times if has gone through
a min/max loop, and code to initialize these counters.  However,
if the pattern that is being matched fails, the code that
re-initializes the max counter is not executed, leaving the
old value for the next time the regex is run.  The solution is
to have the compiler move the max counter initializer to the
start of the min/max loop rather than the end.

There are two patches in the message.  One is for the regex.c
used in sed-1.08, diff-1.15 and whatever other programs use
regex.  The other patch is for regex.c as supplied with sed-1.09.

Rick.

*** sed-1.08/regex.c.orig	Mon Aug 31 14:50:36 1992
--- sed-1.08/regex.c	Mon Aug 31 14:59:22 1992
***************
*** 1011,1031 ****
                       to this jump when matching, we'll have matched once
                       already, so jump back only upper_bound - 1 times.  */
  
                     if (upper_bound > 1)
                       {
!                        store_jump_n (b, jump_n, laststart, upper_bound - 1);
                         b += 5;
                         /* When hit this when matching, reset the
                            preceding jump_n's n to upper_bound - 1.  */
!                        BUFPUSH (set_number_at);
! 		       GET_BUFFER_SPACE (2);
!                        STORE_NUMBER_AND_INCR (b, -5);
!                        STORE_NUMBER_AND_INCR (b, upper_bound - 1);
                       }
- 		   /* When hit this when matching, set the succeed_n's n.  */
-                    GET_BUFFER_SPACE (5);
- 		   insert_op_2 (set_number_at, laststart, b, 5, lower_bound);
-                    b += 5;
                   }
                pending_exact = 0;
  	      beg_interval = 0;
--- 1011,1031 ----
                       to this jump when matching, we'll have matched once
                       already, so jump back only upper_bound - 1 times.  */
  
+ 		   /* When hit this when matching, set the succeed_n's n.  */
+                    GET_BUFFER_SPACE (5);
+ 		   insert_op_2 (set_number_at, laststart, b, 5, lower_bound);
+                    b += 5;
                     if (upper_bound > 1)
                       {
!                        store_jump_n (b, jump_n, laststart + 5, upper_bound - 1);
                         b += 5;
                         /* When hit this when matching, reset the
                            preceding jump_n's n to upper_bound - 1.  */
! 		       GET_BUFFER_SPACE (5);
! 		       insert_op_2 (set_number_at, laststart, b, b - laststart,
! 							upper_bound - 1);
! 		       b += 5;
                       }
                   }
                pending_exact = 0;
  	      beg_interval = 0;
*** sed-1.09/regex.c.orig	Mon Aug 31 15:05:38 1992
--- sed-1.09/regex.c	Mon Aug 31 15:07:40 1992
***************
*** 1754,1759 ****
--- 1754,1764 ----
                       b += 5; 	/* Just increment for the succeed_n here.  */
  
  
+                      /* When hit this when matching, set the succeed_n's n.  */
+                      GET_BUFFER_SPACE (5);
+                      insert_op_2 (set_number_at, laststart, b, 5, lower_bound);
+                      b += 5;
+ 
                      /* More than one repetition is allowed, so put in at
                         the end of the buffer a backward jump from b to the
                         succeed_n we put in above.  By the time we've gotten
***************
*** 1761,1784 ****
                         already, so jump back only upper_bound - 1 times.  */
                       if (upper_bound > 1)
                         {
!                          store_jump_n (b, no_pop_jump_n, laststart, 
                                         upper_bound - 1);
                           b += 5;
  
                           /* When hit this when matching, reset the
                              preceding no_pop_jump_n's n to upper_bound - 1.  */
!                          PAT_PUSH (set_number_at);
! 
!                          /* Only need to get space for the numbers.  */
!                          GET_BUFFER_SPACE (4);
!                          STORE_NUMBER_AND_INCR (b, -5);
!                          STORE_NUMBER_AND_INCR (b, upper_bound - 1);
                         }
- 
-                      /* When hit this when matching, set the succeed_n's n.  */
-                      GET_BUFFER_SPACE (5);
-                      insert_op_2 (set_number_at, laststart, b, 5, lower_bound);
-                      b += 5;
                     }
                  pending_exact = 0;
                  beg_interval = NULL;
--- 1766,1782 ----
                         already, so jump back only upper_bound - 1 times.  */
                       if (upper_bound > 1)
                         {
!                          store_jump_n (b, no_pop_jump_n, laststart + 5, 
                                         upper_bound - 1);
                           b += 5;
  
                           /* When hit this when matching, reset the
                              preceding no_pop_jump_n's n to upper_bound - 1.  */
! 			 GET_BUFFER_SPACE (5);
! 			 insert_op_2 (set_number_at, laststart, b, b - laststart,
! 					upper_bound - 1);
! 			 b += 5;
                         }
                     }
                  pending_exact = 0;
                  beg_interval = NULL;

Newsgroups: gnu.utils.bug