painting: stay within the line when skipping zero-length matches
Don't blithely overshoot the end of a line when both start regex and end regex match an empty string. Overshooting would let the matching run on into uncharted country and thus ultimately cause a segfault. This fixes https://savannah.gnu.org/bugs/?50056. Reported-by: Elia Geretto <elia.f.geretto@gmail.com>master
parent
94907aa534
commit
9de376deed
|
@ -417,6 +417,7 @@ void precalc_multicolorinfo(void)
|
||||||
|
|
||||||
for (fileptr = openfile->fileage; fileptr != NULL; fileptr = fileptr->next) {
|
for (fileptr = openfile->fileage; fileptr != NULL; fileptr = fileptr->next) {
|
||||||
int startx = 0, nostart = 0;
|
int startx = 0, nostart = 0;
|
||||||
|
int linelen = strlen(fileptr->data);
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
fprintf(stderr, "working on lineno %ld... ", (long)fileptr->lineno);
|
fprintf(stderr, "working on lineno %ld... ", (long)fileptr->lineno);
|
||||||
#endif
|
#endif
|
||||||
|
@ -427,6 +428,9 @@ void precalc_multicolorinfo(void)
|
||||||
/* Look for an end, and start marking how many lines are
|
/* Look for an end, and start marking how many lines are
|
||||||
* encompassed, which should speed up rendering later. */
|
* encompassed, which should speed up rendering later. */
|
||||||
startx += startmatch.rm_eo;
|
startx += startmatch.rm_eo;
|
||||||
|
|
||||||
|
if (startx > linelen)
|
||||||
|
break;
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
fprintf(stderr, "start found at pos %lu... ", (unsigned long)startx);
|
fprintf(stderr, "start found at pos %lu... ", (unsigned long)startx);
|
||||||
#endif
|
#endif
|
||||||
|
|
14
src/winio.c
14
src/winio.c
|
@ -2350,6 +2350,8 @@ void edit_draw(filestruct *fileptr, const char *converted,
|
||||||
for (; varnish != NULL; varnish = varnish->next) {
|
for (; varnish != NULL; varnish = varnish->next) {
|
||||||
size_t index = 0;
|
size_t index = 0;
|
||||||
/* Where in the line we currently begin looking for a match. */
|
/* Where in the line we currently begin looking for a match. */
|
||||||
|
int linelen;
|
||||||
|
/* The length of the line we are currently looking at. */
|
||||||
int start_col;
|
int start_col;
|
||||||
/* The starting column of a piece to paint. Zero-based. */
|
/* The starting column of a piece to paint. Zero-based. */
|
||||||
int paintlen = 0;
|
int paintlen = 0;
|
||||||
|
@ -2473,6 +2475,8 @@ void edit_draw(filestruct *fileptr, const char *converted,
|
||||||
start_line->multidata[varnish->id] == CSTARTENDHERE))
|
start_line->multidata[varnish->id] == CSTARTENDHERE))
|
||||||
goto step_two;
|
goto step_two;
|
||||||
|
|
||||||
|
linelen = strlen(start_line->data);
|
||||||
|
|
||||||
/* Now start_line is the first line before fileptr containing
|
/* Now start_line is the first line before fileptr containing
|
||||||
* a start match. Is there a start on that line not followed
|
* a start match. Is there a start on that line not followed
|
||||||
* by an end on that line? */
|
* by an end on that line? */
|
||||||
|
@ -2481,7 +2485,8 @@ void edit_draw(filestruct *fileptr, const char *converted,
|
||||||
index += startmatch.rm_eo;
|
index += startmatch.rm_eo;
|
||||||
/* If the start match is zero-length, don't get stuck. */
|
/* If the start match is zero-length, don't get stuck. */
|
||||||
if (startmatch.rm_so == startmatch.rm_eo)
|
if (startmatch.rm_so == startmatch.rm_eo)
|
||||||
index++;
|
if (++index > linelen)
|
||||||
|
break;
|
||||||
|
|
||||||
/* If there is no end after this last start, good. */
|
/* If there is no end after this last start, good. */
|
||||||
if (regexec(varnish->end, start_line->data + index,
|
if (regexec(varnish->end, start_line->data + index,
|
||||||
|
@ -2534,6 +2539,8 @@ void edit_draw(filestruct *fileptr, const char *converted,
|
||||||
* looking only after an end match, if there is one. */
|
* looking only after an end match, if there is one. */
|
||||||
index = (paintlen == 0) ? 0 : endmatch.rm_eo;
|
index = (paintlen == 0) ? 0 : endmatch.rm_eo;
|
||||||
|
|
||||||
|
linelen = strlen(fileptr->data);
|
||||||
|
|
||||||
while (regexec(varnish->start, fileptr->data + index,
|
while (regexec(varnish->start, fileptr->data + index,
|
||||||
1, &startmatch, (index == 0) ?
|
1, &startmatch, (index == 0) ?
|
||||||
0 : REG_NOTBOL) == 0) {
|
0 : REG_NOTBOL) == 0) {
|
||||||
|
@ -2574,7 +2581,10 @@ void edit_draw(filestruct *fileptr, const char *converted,
|
||||||
/* Skip over a zero-length match. */
|
/* Skip over a zero-length match. */
|
||||||
if (endmatch.rm_so == endmatch.rm_eo)
|
if (endmatch.rm_so == endmatch.rm_eo)
|
||||||
index += 1;
|
index += 1;
|
||||||
continue;
|
if (index > linelen)
|
||||||
|
break;
|
||||||
|
else
|
||||||
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* There is no end on this line. But maybe on later lines? */
|
/* There is no end on this line. But maybe on later lines? */
|
||||||
|
|
Loading…
Reference in New Issue