From add945e717f6c2392622f665390b8d586bf183e4 Mon Sep 17 00:00:00 2001 From: Benno Schulenberg Date: Sat, 25 May 2024 12:02:33 +0200 Subject: [PATCH] files: look for digits and colons starting from the end of the filename Starting from the end of the provided filename avoids needlessly looking at colons that are somewhere in the middle of the path or the filename. It also avoids inconsistenly interpreting a specified line number as a column number when the filename itself ends with a colon plus digits and the filename without the colon plus digits exists too. This also removes the eliding of a backslash before a colon, which would mangle the filename if the name actually contained a backslash followed by a colon. Negative line and column numbers are no longer allowed when using the colon notation. This fixes https://savannah.gnu.org/bugs/?65781, and fixes https://savannah.gnu.org/bugs/?65782. Problems existed since version 8.0, since colon parsing was introduced. --- src/nano.c | 32 ++++++++++++++++---------------- 1 file changed, 16 insertions(+), 16 deletions(-) diff --git a/src/nano.c b/src/nano.c index 123af18d..5707bd96 100644 --- a/src/nano.c +++ b/src/nano.c @@ -2500,24 +2500,24 @@ int main(int argc, char **argv) struct stat fileinfo; /* If the filename contains a colon and this file does not exist, - * then check if the filename ends with a number (while skipping - * any colon preceded by a backslash and eliding the backslash). - * If there is a valid trailing number, chop colon and number off. + * then check if the filename ends with digits preceded by a colon + * (possibly preceded by more digits and a colon). If there is or + * are such trailing numbers, chop the colons plus numbers off. * The number is later used to place the cursor on that line. */ if (strchr(filename, ':') && stat(filename, &fileinfo) < 0) { - char *colon = filename + (*filename ? 1 : 0); - - while ((colon = strchr(colon, ':'))) { - if (*(colon - 1) == '\\') - memmove(colon - 1, colon, strlen(colon) + 1); - else if (parse_line_column(colon + 1, &givenline, &givencol)) { - *colon = '\0'; - if (stat(filename, &fileinfo) < 0) { - *colon++ = ':'; - givencol = 0; - } - } else - ++colon; + char *coda = filename + strlen(filename); + maybe_two: + while (--coda > filename + 1 && ('0' <= *coda && *coda <= '9')) + ; + if (*coda == ':' && ('0' <= *(coda + 1) && *(coda +1) <= '9')) { + *coda = '\0'; + if (stat(filename, &fileinfo) < 0) { + *coda = ':'; + /* If this was the first colon, look for a second one. */ + if (!strchr(coda + 1, ':')) + goto maybe_two; + } else if (!parse_line_column(coda + 1, &givenline, &givencol)) + die(_("Invalid number\n")); } }