in 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="$"" git-svn-id: svn://svn.savannah.gnu.org/nano/trunk/nano@3484 35c25a1d-7b9e-4130-9fde-d3aeb78583b8master
parent
c7b9e15e9a
commit
a5f833de42
|
@ -198,6 +198,11 @@ CVS code -
|
||||||
- Add Ctrl-/ as an alias for Ctrl-_. (DLR, found by Benno
|
- Add Ctrl-/ as an alias for Ctrl-_. (DLR, found by Benno
|
||||||
Schulenberg)
|
Schulenberg)
|
||||||
- Simplify the if blocks wherever possible. (DLR)
|
- 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:
|
- configure.ac:
|
||||||
- Remove old warnings about color support. (DLR)
|
- Remove old warnings about color support. (DLR)
|
||||||
- doc/faq.html:
|
- doc/faq.html:
|
||||||
|
|
204
src/winio.c
204
src/winio.c
|
@ -2450,129 +2450,135 @@ void edit_draw(const filestruct *fileptr, const char *converted, int
|
||||||
goto step_two;
|
goto step_two;
|
||||||
start_line = start_line->prev;
|
start_line = start_line->prev;
|
||||||
}
|
}
|
||||||
/* No start found, so skip to the next step. */
|
if (startmatch.rm_so == startmatch.rm_eo) {
|
||||||
if (start_line == NULL)
|
startmatch.rm_eo++;
|
||||||
goto step_two;
|
statusbar(_("Refusing zero-length regex match"));
|
||||||
/* Now start_line is the first line before fileptr
|
} else {
|
||||||
* containing a start match. Is there a start on this
|
/* No start found, so skip to the next step. */
|
||||||
* line not followed by an end on this line? */
|
if (start_line == NULL)
|
||||||
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;
|
goto step_two;
|
||||||
}
|
/* Now start_line is the first line before fileptr
|
||||||
/* Indeed, there is a start not followed on this line by
|
* containing a start match. Is there a start on
|
||||||
* an end. */
|
* 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
|
/* We have already checked that there is no end
|
||||||
* fileptr and after the start. Is there an end after
|
* before fileptr and after the start. Is there an
|
||||||
* the start at all? We don't paint unterminated
|
* end after the start at all? We don't paint
|
||||||
* starts. */
|
* unterminated starts. */
|
||||||
end_line = fileptr;
|
end_line = fileptr;
|
||||||
while (end_line != NULL && regexec(tmpcolor->end,
|
while (end_line != NULL && regexec(tmpcolor->end,
|
||||||
end_line->data, 1, &endmatch, 0) == REG_NOMATCH)
|
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. */
|
/* No end found, or it is too early. */
|
||||||
if (end_line == NULL || (end_line == fileptr &&
|
if (end_line == NULL || (end_line == fileptr &&
|
||||||
endmatch.rm_eo <= startpos))
|
endmatch.rm_eo <= startpos))
|
||||||
goto step_two;
|
goto step_two;
|
||||||
|
|
||||||
/* Now paint the start of fileptr. */
|
/* Now paint the start of fileptr. */
|
||||||
if (end_line != fileptr)
|
if (end_line != fileptr)
|
||||||
/* If the start of fileptr is on a different line
|
/* If the start of fileptr is on a different
|
||||||
* from the end, paintlen is -1, meaning that
|
* line from the end, paintlen is -1, meaning
|
||||||
* everything on the line gets painted. */
|
* that everything on the line gets painted. */
|
||||||
paintlen = -1;
|
paintlen = -1;
|
||||||
else
|
else
|
||||||
/* Otherwise, paintlen is the expanded location of
|
/* Otherwise, paintlen is the expanded location
|
||||||
* the end of the match minus the expanded location
|
* of the end of the match minus the expanded
|
||||||
* of the beginning of the page. */
|
* location of the beginning of the page. */
|
||||||
paintlen = actual_x(converted,
|
paintlen = actual_x(converted,
|
||||||
strnlenpt(fileptr->data, endmatch.rm_eo) -
|
strnlenpt(fileptr->data,
|
||||||
start);
|
endmatch.rm_eo) - start);
|
||||||
|
|
||||||
mvwaddnstr(edit, line, 0, converted, paintlen);
|
mvwaddnstr(edit, line, 0, converted, paintlen);
|
||||||
|
|
||||||
step_two:
|
step_two:
|
||||||
/* Second step, we look for starts on this line. */
|
/* Second step, we look for starts on this line. */
|
||||||
start_col = 0;
|
start_col = 0;
|
||||||
|
|
||||||
while (start_col < endpos) {
|
while (start_col < endpos) {
|
||||||
if (regexec(tmpcolor->start, fileptr->data +
|
if (regexec(tmpcolor->start, fileptr->data +
|
||||||
start_col, 1, &startmatch, (start_col == 0) ?
|
start_col, 1, &startmatch, (start_col ==
|
||||||
0 : REG_NOTBOL) == REG_NOMATCH || start_col +
|
0) ? 0 : REG_NOTBOL) == REG_NOMATCH ||
|
||||||
startmatch.rm_so >= endpos)
|
start_col + startmatch.rm_so >= endpos)
|
||||||
/* No more starts on this line. */
|
/* No more starts on this line. */
|
||||||
break;
|
break;
|
||||||
/* Translate the match to be relative to the
|
/* Translate the match to be relative to the
|
||||||
* beginning of the line. */
|
* beginning of the line. */
|
||||||
startmatch.rm_so += start_col;
|
startmatch.rm_so += start_col;
|
||||||
startmatch.rm_eo += start_col;
|
startmatch.rm_eo += start_col;
|
||||||
|
|
||||||
if (startmatch.rm_so <= startpos)
|
x_start = (startmatch.rm_so <= startpos) ? 0 :
|
||||||
x_start = 0;
|
strnlenpt(fileptr->data,
|
||||||
else
|
|
||||||
x_start = strnlenpt(fileptr->data,
|
|
||||||
startmatch.rm_so) - start;
|
startmatch.rm_so) - start;
|
||||||
|
|
||||||
index = actual_x(converted, x_start);
|
index = actual_x(converted, x_start);
|
||||||
|
|
||||||
if (regexec(tmpcolor->end, fileptr->data +
|
if (regexec(tmpcolor->end, fileptr->data +
|
||||||
startmatch.rm_eo, 1, &endmatch,
|
startmatch.rm_eo, 1, &endmatch,
|
||||||
(startmatch.rm_eo == 0) ? 0 : REG_NOTBOL) ==
|
(startmatch.rm_eo == 0) ? 0 :
|
||||||
0) {
|
REG_NOTBOL) == 0) {
|
||||||
/* Translate the end match to be relative to the
|
/* Translate the end match to be relative to
|
||||||
* beginning of the line. */
|
* the beginning of the line. */
|
||||||
endmatch.rm_so += startmatch.rm_eo;
|
endmatch.rm_so += startmatch.rm_eo;
|
||||||
endmatch.rm_eo += startmatch.rm_eo;
|
endmatch.rm_eo += startmatch.rm_eo;
|
||||||
/* There is an end on this line. But does it
|
/* There is an end on this line. But does
|
||||||
* appear on this page, and is the match more
|
* it appear on this page, and is the match
|
||||||
* than zero characters long? */
|
* more than zero characters long? */
|
||||||
if (endmatch.rm_eo > startpos &&
|
if (endmatch.rm_eo > startpos &&
|
||||||
endmatch.rm_eo > startmatch.rm_so) {
|
endmatch.rm_eo > startmatch.rm_so) {
|
||||||
paintlen = actual_x(converted + index,
|
paintlen = actual_x(converted + index,
|
||||||
strnlenpt(fileptr->data,
|
strnlenpt(fileptr->data,
|
||||||
endmatch.rm_eo) - start - x_start);
|
endmatch.rm_eo) - start -
|
||||||
|
x_start);
|
||||||
|
|
||||||
assert(0 <= x_start && x_start < COLS);
|
assert(0 <= x_start && x_start < COLS);
|
||||||
|
|
||||||
mvwaddnstr(edit, line, x_start, converted +
|
mvwaddnstr(edit, line, x_start,
|
||||||
index, paintlen);
|
converted + index, paintlen);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
/* There is no end on this line. But we haven't
|
/* There is no end on this line. But we
|
||||||
* yet looked for one on later lines. */
|
* haven't yet looked for one on later
|
||||||
end_line = fileptr->next;
|
* lines. */
|
||||||
|
end_line = fileptr->next;
|
||||||
|
|
||||||
while (end_line != NULL &&
|
while (end_line != NULL &&
|
||||||
regexec(tmpcolor->end, end_line->data,
|
regexec(tmpcolor->end, end_line->data,
|
||||||
0, NULL, 0) == REG_NOMATCH)
|
0, NULL, 0) == REG_NOMATCH)
|
||||||
end_line = end_line->next;
|
end_line = end_line->next;
|
||||||
|
|
||||||
if (end_line != NULL) {
|
if (end_line != NULL) {
|
||||||
assert(0 <= x_start && x_start < COLS);
|
assert(0 <= x_start && x_start < COLS);
|
||||||
|
|
||||||
mvwaddnstr(edit, line, x_start, converted +
|
mvwaddnstr(edit, line, x_start,
|
||||||
index, -1);
|
converted + index, -1);
|
||||||
/* We painted to the end of the line, so
|
/* We painted to the end of the line, so
|
||||||
* don't bother checking any more starts. */
|
* don't bother checking any more
|
||||||
break;
|
* starts. */
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
start_col = startmatch.rm_so + 1;
|
||||||
}
|
}
|
||||||
start_col = startmatch.rm_so + 1;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue