]> git.wh0rd.org Git - nano.git/commitdiff
in edit_draw(), properly ignore zero-length regexes in multi-line
authorDavid Lawrence Ramsey <pooka109@gmail.com>
Mon, 8 May 2006 15:57:04 +0000 (15:57 +0000)
committerDavid Lawrence Ramsey <pooka109@gmail.com>
Mon, 8 May 2006 15:57:04 +0000 (15:57 +0000)
regexes as well as single-line ones; this avoids a segfault when trying
to color e.g. "start="$" end="$""

git-svn-id: svn://svn.savannah.gnu.org/nano/trunk/nano@3484 35c25a1d-7b9e-4130-9fde-d3aeb78583b8

ChangeLog
src/winio.c

index 0bbca061095da79896ca793f1055824f70f05f98..ec01bd62745a8ad36caf2a022239ccfbff50cfdf 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -198,6 +198,11 @@ CVS code -
        - Add Ctrl-/ as an alias for Ctrl-_. (DLR, found by Benno
          Schulenberg)
        - Simplify the if blocks wherever possible. (DLR)
+  edit_draw()
+       - Properly ignore zero-length regexes in multi-line regexes as
+         well as single-line ones.  This avoids a segfault when trying
+         to color e.g. "start="$" end="$"". (DLR, found by Trevor
+         Caira)
 - configure.ac:
        - Remove old warnings about color support. (DLR)
 - doc/faq.html:
index 31e29bf8f7839796d31f20e89c97cf8325d43538..de0c0cc2a35633175eceb5be133972afdab6b67b 100644 (file)
@@ -2450,129 +2450,135 @@ void edit_draw(const filestruct *fileptr, const char *converted, int
                        goto step_two;
                    start_line = start_line->prev;
                }
-               /* No start found, so skip to the next step. */
-               if (start_line == NULL)
-                   goto step_two;
-               /* Now start_line is the first line before fileptr
-                * containing a start match.  Is there a start on this
-                * line not followed by an end on this line? */
-               start_col = 0;
-               while (TRUE) {
-                   start_col += startmatch.rm_so;
-                   startmatch.rm_eo -= startmatch.rm_so;
-                   if (regexec(tmpcolor->end, start_line->data +
-                       start_col + startmatch.rm_eo, 0, NULL,
-                       (start_col + startmatch.rm_eo == 0) ? 0 :
-                       REG_NOTBOL) == REG_NOMATCH)
-                       /* No end found after this start. */
-                       break;
-                   start_col++;
-                   if (regexec(tmpcolor->start, start_line->data +
-                       start_col, 1, &startmatch, REG_NOTBOL) ==
-                       REG_NOMATCH)
-                       /* No later start on this line. */
+               if (startmatch.rm_so == startmatch.rm_eo) {
+                   startmatch.rm_eo++;
+                   statusbar(_("Refusing zero-length regex match"));
+               } else {
+                   /* No start found, so skip to the next step. */
+                   if (start_line == NULL)
                        goto step_two;
-               }
-               /* Indeed, there is a start not followed on this line by
-                * an end. */
-
-               /* We have already checked that there is no end before
-                * fileptr and after the start.  Is there an end after
-                * the start at all?  We don't paint unterminated
-                * starts. */
-               end_line = fileptr;
-               while (end_line != NULL && regexec(tmpcolor->end,
+                   /* Now start_line is the first line before fileptr
+                    * containing a start match.  Is there a start on
+                    * this line not followed by an end on this line? */
+                   start_col = 0;
+                   while (TRUE) {
+                       start_col += startmatch.rm_so;
+                       startmatch.rm_eo -= startmatch.rm_so;
+                       if (regexec(tmpcolor->end, start_line->data +
+                               start_col + startmatch.rm_eo, 0, NULL,
+                               (start_col + startmatch.rm_eo == 0) ?
+                               0 : REG_NOTBOL) == REG_NOMATCH)
+                           /* No end found after this start. */
+                           break;
+                       start_col++;
+                       if (regexec(tmpcolor->start, start_line->data +
+                               start_col, 1, &startmatch,
+                               REG_NOTBOL) == REG_NOMATCH)
+                           /* No later start on this line. */
+                           goto step_two;
+                   }
+                   /* Indeed, there is a start not followed on this
+                    * line by an end. */
+
+                   /* We have already checked that there is no end
+                    * before fileptr and after the start.  Is there an
+                    * end after the start at all?  We don't paint
+                    * unterminated starts. */
+                   end_line = fileptr;
+                   while (end_line != NULL && regexec(tmpcolor->end,
                        end_line->data, 1, &endmatch, 0) == REG_NOMATCH)
-                   end_line = end_line->next;
+                       end_line = end_line->next;
 
-               /* No end found, or it is too early. */
-               if (end_line == NULL || (end_line == fileptr &&
+                   /* No end found, or it is too early. */
+                   if (end_line == NULL || (end_line == fileptr &&
                        endmatch.rm_eo <= startpos))
-                   goto step_two;
-
-               /* Now paint the start of fileptr. */
-               if (end_line != fileptr)
-                   /* If the start of fileptr is on a different line
-                    * from the end, paintlen is -1, meaning that
-                    * everything on the line gets painted. */
-                   paintlen = -1;
-               else
-                   /* Otherwise, paintlen is the expanded location of
-                    * the end of the match minus the expanded location
-                    * of the beginning of the page. */
-                   paintlen = actual_x(converted,
-                       strnlenpt(fileptr->data, endmatch.rm_eo) -
-                       start);
-
-               mvwaddnstr(edit, line, 0, converted, paintlen);
+                       goto step_two;
 
-  step_two:
-               /* Second step, we look for starts on this line. */
-               start_col = 0;
-
-               while (start_col < endpos) {
-                   if (regexec(tmpcolor->start, fileptr->data +
-                       start_col, 1, &startmatch, (start_col == 0) ?
-                       0 : REG_NOTBOL) == REG_NOMATCH || start_col +
-                       startmatch.rm_so >= endpos)
-                       /* No more starts on this line. */
-                       break;
-                   /* Translate the match to be relative to the
-                    * beginning of the line. */
-                   startmatch.rm_so += start_col;
-                   startmatch.rm_eo += start_col;
-
-                   if (startmatch.rm_so <= startpos)
-                       x_start = 0;
+                   /* Now paint the start of fileptr. */
+                   if (end_line != fileptr)
+                       /* If the start of fileptr is on a different
+                        * line from the end, paintlen is -1, meaning
+                        * that everything on the line gets painted. */
+                       paintlen = -1;
                    else
-                       x_start = strnlenpt(fileptr->data,
-                               startmatch.rm_so) - start;
+                       /* Otherwise, paintlen is the expanded location
+                        * of the end of the match minus the expanded
+                        * location of the beginning of the page. */
+                       paintlen = actual_x(converted,
+                               strnlenpt(fileptr->data,
+                               endmatch.rm_eo) - start);
 
-                   index = actual_x(converted, x_start);
+                   mvwaddnstr(edit, line, 0, converted, paintlen);
 
-                   if (regexec(tmpcolor->end, fileptr->data +
-                       startmatch.rm_eo, 1, &endmatch,
-                       (startmatch.rm_eo == 0) ? 0 : REG_NOTBOL) ==
-                       0) {
-                       /* Translate the end match to be relative to the
+  step_two:
+                   /* Second step, we look for starts on this line. */
+                   start_col = 0;
+
+                   while (start_col < endpos) {
+                       if (regexec(tmpcolor->start, fileptr->data +
+                               start_col, 1, &startmatch, (start_col ==
+                               0) ? 0 : REG_NOTBOL) == REG_NOMATCH ||
+                               start_col + startmatch.rm_so >= endpos)
+                           /* No more starts on this line. */
+                           break;
+                       /* Translate the match to be relative to the
                         * beginning of the line. */
-                       endmatch.rm_so += startmatch.rm_eo;
-                       endmatch.rm_eo += startmatch.rm_eo;
-                       /* There is an end on this line.  But does it
-                        * appear on this page, and is the match more
-                        * than zero characters long? */
-                       if (endmatch.rm_eo > startpos &&
-                               endmatch.rm_eo > startmatch.rm_so) {
-                           paintlen = actual_x(converted + index,
+                       startmatch.rm_so += start_col;
+                       startmatch.rm_eo += start_col;
+
+                       x_start = (startmatch.rm_so <= startpos) ? 0 :
                                strnlenpt(fileptr->data,
-                               endmatch.rm_eo) - start - x_start);
+                               startmatch.rm_so) - start;
 
-                           assert(0 <= x_start && x_start < COLS);
+                       index = actual_x(converted, x_start);
 
-                           mvwaddnstr(edit, line, x_start, converted +
-                               index, paintlen);
-                       }
-                   } else {
-                       /* There is no end on this line.  But we haven't
-                        * yet looked for one on later lines. */
-                       end_line = fileptr->next;
+                       if (regexec(tmpcolor->end, fileptr->data +
+                               startmatch.rm_eo, 1, &endmatch,
+                               (startmatch.rm_eo == 0) ? 0 :
+                               REG_NOTBOL) == 0) {
+                           /* Translate the end match to be relative to
+                            * the beginning of the line. */
+                           endmatch.rm_so += startmatch.rm_eo;
+                           endmatch.rm_eo += startmatch.rm_eo;
+                           /* There is an end on this line.  But does
+                            * it appear on this page, and is the match
+                            * more than zero characters long? */
+                           if (endmatch.rm_eo > startpos &&
+                               endmatch.rm_eo > startmatch.rm_so) {
+                               paintlen = actual_x(converted + index,
+                                       strnlenpt(fileptr->data,
+                                       endmatch.rm_eo) - start -
+                                       x_start);
 
-                       while (end_line != NULL &&
+                               assert(0 <= x_start && x_start < COLS);
+
+                               mvwaddnstr(edit, line, x_start,
+                                       converted + index, paintlen);
+                           }
+                       } else {
+                           /* There is no end on this line.  But we
+                            * haven't yet looked for one on later
+                            * lines. */
+                           end_line = fileptr->next;
+
+                           while (end_line != NULL &&
                                regexec(tmpcolor->end, end_line->data,
                                0, NULL, 0) == REG_NOMATCH)
-                           end_line = end_line->next;
+                               end_line = end_line->next;
 
-                       if (end_line != NULL) {
-                           assert(0 <= x_start && x_start < COLS);
+                           if (end_line != NULL) {
+                               assert(0 <= x_start && x_start < COLS);
 
-                           mvwaddnstr(edit, line, x_start, converted +
-                               index, -1);
-                           /* We painted to the end of the line, so
-                            * don't bother checking any more starts. */
-                           break;
+                               mvwaddnstr(edit, line, x_start,
+                                       converted + index, -1);
+                               /* We painted to the end of the line, so
+                                * don't bother checking any more
+                                * starts. */
+                               break;
+                           }
                        }
+                       start_col = startmatch.rm_so + 1;
                    }
-                   start_col = startmatch.rm_so + 1;
                }
            }