diff -ur nano-1.3.0-p2/src/color.c nano-1.3.0-p2.1/src/color.c --- nano-1.3.0-p2/src/color.c 2003-11-13 15:35:28.000000000 -0700 +++ nano-1.3.0-p2.1/src/color.c 2003-12-19 18:15:50.000000000 -0700 @@ -101,7 +101,7 @@ /* Update the color information based on the current filename. */ void update_color(void) { - syntaxtype *tmpsyntax; + syntaxtype *tmpsyntax = NULL; colorstrings = NULL; @@ -113,7 +113,7 @@ return; for (tmpsyntax = syntaxes; tmpsyntax != NULL; tmpsyntax = tmpsyntax->next) { - if(tmpsyntax->desc == NULL) { + if (tmpsyntax->desc == NULL) { if (!strcasecmp("default", syntaxstr)) { colorstrings = tmpsyntax->colors; break; @@ -137,12 +137,10 @@ if (tmpsyntax->desc == NULL) continue; - /* should file extensions be case-insensitive? */ - regcomp(&preg, e->ext_regex, REG_EXTENDED | REG_NOSUB); - /* Set colorstrings if we matched the extension regex */ - if (!regexec(&preg, filename, 0, NULL, 0)) { + /* set colorstrings if we matched the extension regex */ + if (regexec(&preg, filename, 0, NULL, 0) == 0) { colorstrings = tmpsyntax->colors; regfree(&preg); break; @@ -156,7 +154,7 @@ /* is there a default syntax? */ if (colorstrings == NULL) - for(tmpsyntax = syntaxes; tmpsyntax != NULL; tmpsyntax = tmpsyntax->next) + for (tmpsyntax = syntaxes; tmpsyntax != NULL; tmpsyntax = tmpsyntax->next) if (tmpsyntax->desc == NULL) { colorstrings = tmpsyntax->colors; break; @@ -188,6 +186,15 @@ int regexec_wrapper(const colortype *color, const regex_t *preg, const char *string, size_t nmatch, regmatch_t pmatch[], int eflags) { + /* Color patch 1 introduced a bug that causes nano to randomly + * segfault or lockup when resizing the window. This can be + * reproduced by rapidly resizing the window of a highlighted + * file. */ + + /* A hack to prevent crashes while resizing window */ + if (color->counter == -1) + return REG_NOMATCH; + /* Each regex_t will be freed and recompiled every 100 calls */ if (color->counter > 100) { /* calls kB (maximum regexec leakage) @@ -199,6 +206,9 @@ * 50 20 */ + /* A hack to prevent crashes while resizing window */ + ((colortype *)color)->counter = -1; + regfree((regex_t *)&color->start); regcomp((regex_t *)&color->start, color->start_regex, (color->flags.insensitive ? REG_ICASE : 0) | REG_EXTENDED); diff -ur nano-1.3.0-p2/src/nano.h nano-1.3.0-p2.1/src/nano.h --- nano-1.3.0-p2/src/nano.h 2003-11-08 23:57:05.000000000 -0700 +++ nano-1.3.0-p2.1/src/nano.h 2003-12-19 17:30:34.000000000 -0700 @@ -201,8 +201,8 @@ typedef struct colortype { struct { - int insensitive:1; /* case-insensitive matches */ - int defaultcolor:1; /* default color for syntax - no regexps */ + int insensitive : 1; /* case-insensitive matches */ + int defaultcolor : 1; /* default color for syntax - no regexps */ } flags; int fg; /* fg color */ int bg; /* bg color */ @@ -217,15 +217,18 @@ } colortype; typedef struct exttype { - char *ext_regex; /* The file extensions that match this syntax. */ + char *ext_regex; /* The file extensions that match this + * syntax */ struct exttype *next; } exttype; typedef struct syntaxtype { int compiled; /* Set when color list has been compiled */ char *desc; /* Name of this syntax */ - exttype *extensions; /* List of file extensions that this syntax applies to */ - colortype *colors; /* List of color expression used by this syntax */ + exttype *extensions; /* List of file extensions that this + * syntax applies to */ + colortype *colors; /* List of color expression used by this + * syntax */ struct syntaxtype *next; } syntaxtype; diff -ur nano-1.3.0-p2/src/proto.h nano-1.3.0-p2.1/src/proto.h --- nano-1.3.0-p2/src/proto.h 2003-11-08 23:05:44.000000000 -0700 +++ nano-1.3.0-p2.1/src/proto.h 2003-12-19 17:30:57.000000000 -0700 @@ -347,7 +347,7 @@ char *parse_next_regex(char *ptr); int nregcomp(const char *regex, int flags); int parse_syntax(char *ptr); -int parse_defaultsyntax(char *ptr); +int parse_default_syntax(char *ptr); void parse_colors(char *ptr, int ctflags); #endif /* ENABLE_COLOR */ void parse_rcfile(FILE *rcstream, int color_only); diff -ur nano-1.3.0-p2/src/rcfile.c nano-1.3.0-p2.1/src/rcfile.c --- nano-1.3.0-p2/src/rcfile.c 2003-11-09 00:50:06.000000000 -0700 +++ nano-1.3.0-p2.1/src/rcfile.c 2003-12-19 18:22:31.000000000 -0700 @@ -243,7 +243,7 @@ } /* Compile the regular expression regex to preg. - Returns FALSE on success, TRUE if the expression is invalid. */ + * Returns FALSE on success, TRUE if the expression is invalid. */ int nregcomp(const char *regex, int flags) { regex_t preg; @@ -261,40 +261,44 @@ return rc != 0; } -/* Free a syntax -- needed so users can override syntaxes from /etc/nanorc */ +/* Free a syntax. Needed so users can override syntaxes from + * /etc/nanorc. */ void free_syntax(syntaxtype *prevsyntax, syntaxtype *syntax) { exttype *ext = syntax->extensions; colortype *color = syntax->colors; - if (prevsyntax) + if (prevsyntax != NULL) prevsyntax->next = syntax->next; - else syntaxes = syntax->next; + else + syntaxes = syntax->next; while (ext != NULL) { exttype *nextext = ext->next; - if (ext->ext_regex) free(ext->ext_regex); + if (ext->ext_regex != NULL) + free(ext->ext_regex); free(ext); ext = nextext; } while (color != NULL) { colortype *nextcolor = color->next; - if (color->start_regex) free(color->start_regex); - if (color->end_regex) free(color->end_regex); + if (color->start_regex != NULL) + free(color->start_regex); + if (color->end_regex != NULL) + free(color->end_regex); free(color); color = nextcolor; } free(syntax); } -/* Create a normal syntax */ +/* Create a normal syntax. */ int parse_syntax(char *ptr) { syntaxtype *tmpsyntax, *prevsyntax = NULL; const char *fileregptr = NULL, *nameptr = NULL; exttype *endext = NULL; /* The end of the extensions list for this syntax. */ - char *name; while (*ptr == ' ') ptr++; @@ -305,7 +309,7 @@ } if (*ptr != '"') { - rcfile_error(_("Regex strings must begin and end with a \" character\n")); + rcfile_error(_("Regex strings must begin and end with a \" character")); return 0; } ptr++; @@ -335,7 +339,8 @@ /* remove existing syntaxes with same name */ if (tmpsyntax->desc != NULL && !strcasecmp(nameptr, tmpsyntax->desc)) free_syntax(prevsyntax, tmpsyntax); - else prevsyntax = tmpsyntax; + else + prevsyntax = tmpsyntax; tmpsyntax = next; } @@ -372,7 +377,7 @@ newext = (exttype *)nmalloc(sizeof(exttype)); newext->ext_regex = mallocstrcpy(NULL, fileregptr); - if (nregcomp(fileregptr, REG_NOSUB)) { + if (nregcomp(fileregptr, REG_NOSUB) == 1) { free(newext->ext_regex); free(newext); } else { @@ -387,8 +392,8 @@ return 1; } -/* Create a default syntax */ -int parse_defaultsyntax(char *ptr) +/* Create a default syntax. */ +int parse_default_syntax(char *ptr) { syntaxtype *tmpsyntax, *prevsyntax = NULL; @@ -435,8 +440,8 @@ void parse_include(char *ptr) { FILE *rc; - char *option, *full_option, *err_filename = NULL, *err_message; - char *old_nanorc = nanorc; + struct stat fileinfo; + char *option, *full_option, *old_nanorc = nanorc; int old_lineno = lineno; option = ptr; @@ -453,36 +458,40 @@ full_option = get_full_path(option); if (full_option == NULL) { - err_filename = option; - err_message = strerror(errno); - } else if (full_option[strlen(full_option) - 1] == '/') { - err_filename = full_option; - err_message = _("Not a file\n"); - } else if ((rc = fopen(full_option, "r")) == NULL) { - err_filename = full_option; - err_message = strerror(errno); - } - if (err_filename != NULL) - rcfile_error(_("Unable to read file %s, %s"), err_filename, err_message); - else { - /* Use the name and line number position of the file while - * parsing it, so we can know where any errors in it are. */ - nanorc = full_option; - lineno = 0; - - parse_rcfile(rc, 1); - fclose(rc); - free(full_option); - - /* We're done with the file; set the name and line number - * position back to those of the old file. */ - nanorc = old_nanorc; - lineno = old_lineno; + rcfile_error(_("Error reading %s: %s"), option, strerror(errno)); + goto cleanup_include; + } + + if ((stat(full_option, &fileinfo) != -1 && (S_ISDIR(fileinfo.st_mode) + || S_ISCHR(fileinfo.st_mode) || S_ISBLK(fileinfo.st_mode)))) { + rcfile_error(_("Error reading %s: %s"), full_option, _("Not a file")); + goto cleanup_include; + } + + if ((rc = fopen(full_option, "r")) == NULL) { + rcfile_error(_("Error reading %s: %s"), full_option, strerror(errno)); + goto cleanup_include; } + + /* Use the name and line number position of the file while parsing + * it, so we can know where any errors in it are. */ + nanorc = full_option; + lineno = 0; + + parse_rcfile(rc, 1); + fclose(rc); + + /* We're done with the file; set the name and line number position + * back to those of the old file. */ + nanorc = old_nanorc; + lineno = old_lineno; + + cleanup_include: + free(full_option); } -#define CTFLAG_INSENSITIVE 1 -#define CTFLAG_DEFAULTCOLOR 2 +#define CTFLAG_INSENSITIVE (1<<0) +#define CTFLAG_DEFAULTCOLOR (1<<1) /* Parse the color stuff into the colorstrings array */ void parse_colors(char *ptr, int ctflags) @@ -578,7 +587,7 @@ } if (*ptr != '"') { - rcfile_error(_("Regex strings must begin and end with a \" character\n")); + rcfile_error(_("Regex strings must begin and end with a \" character")); ptr = parse_next_regex(ptr); continue; } @@ -590,7 +599,7 @@ ptr = parse_next_regex(ptr); newcolor->start_regex = mallocstrcpy(NULL, fgstr); - if (nregcomp(fgstr, ctflags & CTFLAG_INSENSITIVE ? REG_ICASE : 0)) { + if (nregcomp(fgstr, ctflags & CTFLAG_INSENSITIVE ? REG_ICASE : 0) == 1) { free(newcolor->start_regex); free(newcolor); cancelled = 1; @@ -634,7 +643,7 @@ ptr += 4; if (*ptr != '"') { - rcfile_error(_("Regex strings must begin and end with a \" character\n")); + rcfile_error(_("Regex strings must begin and end with a \" character")); continue; } ptr++; @@ -647,7 +656,7 @@ if (cancelled) continue; newcolor->end_regex = mallocstrcpy(NULL, fgstr); - if (nregcomp(fgstr, ctflags & CTFLAG_INSENSITIVE ? REG_ICASE : 0)) { + if (nregcomp(fgstr, ctflags & CTFLAG_INSENSITIVE ? REG_ICASE : 0) == 1) { free(newcolor->end_regex); newcolor->end_regex = NULL; } @@ -716,7 +725,7 @@ if (color_only) { rcfile_error(_("-- Cannot use a default-syntax directive inside included files --")); } else { - syntax_ok = parse_defaultsyntax(ptr); + syntax_ok = parse_default_syntax(ptr); syntax = 1; } } else if (!strcasecmp(keyword, "include")) { @@ -949,7 +958,7 @@ if (ISSET(DISPLAY_SYNTAX)) { const syntaxtype *tmpsyntax; - for(tmpsyntax = syntaxes; tmpsyntax != NULL; tmpsyntax = tmpsyntax->next) { + for (tmpsyntax = syntaxes; tmpsyntax != NULL; tmpsyntax = tmpsyntax->next) { const exttype *ext; for (ext = tmpsyntax->extensions; ext != NULL; ext = ext->next)