From b96388ee957a8b9a8ffaa11729b0bf7a0ccbcf37 Mon Sep 17 00:00:00 2001 From: Charlie Gordon Date: Sun, 7 Aug 2022 03:29:18 +0200 Subject: [PATCH] Fix infinite loop in memfind() - memfind used to loop forever trying to match shell_handlers - match python2.8 and python3 in shbang line - bump version to 5.3.1d - this fixes #1 reported by cmsigler, thank you --- VERSION | 2 +- lang/python.c | 3 +- tests/testfile.py.c | 5 ++ util.c | 126 +++++++++----------------------------------- 4 files changed, 32 insertions(+), 104 deletions(-) create mode 100644 tests/testfile.py.c diff --git a/VERSION b/VERSION index 98fb85d..7648453 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -5.3.1c +5.3.1d diff --git a/lang/python.c b/lang/python.c index 2402253..b5458f0 100644 --- a/lang/python.c +++ b/lang/python.c @@ -308,7 +308,8 @@ static void python_colorize_line(QEColorizeContext *cp, static ModeDef python_mode = { .name = "Python", .extensions = "py|pyt", - .shell_handlers = "python|python2.6|python2.7", + // XXX: should accept wildcards "python*" + .shell_handlers = "python|python2.6|python2.7|python2.8|python3", .keywords = python_keywords, .colorize_func = python_colorize_line, .colorize_flags = PYTHON_PYTHON, diff --git a/tests/testfile.py.c b/tests/testfile.py.c new file mode 100644 index 0000000..16ede66 --- /dev/null +++ b/tests/testfile.py.c @@ -0,0 +1,5 @@ +#!/usr/bin/env python3 + +if name == 'main': +print('It worked!') +exit(0) diff --git a/util.c b/util.c index 534a404..f691373 100644 --- a/util.c +++ b/util.c @@ -392,7 +392,7 @@ int match_shell_handler(const char *p, const char *list) if (memfind(list, base, p - base)) return 1; if (p - base == 3 && !memcmp(base, "env", 3)) { - while (*p != '\0' && *p != '\n') { + while (*p && *p != '\n') { for (; qe_isblank(*p); p++) continue; base = p; @@ -530,115 +530,37 @@ int qe_skip_spaces(const char **pp) return c; } -int memfind(const char *list, const char *s, int len) -{ - const char *q = list; +int memfind(const char *list, const char *s, int len) { + const char *q = list, *start; + int i, j; - if (!q) - return 0; - - for (;;) { - int i = 0; - for (;;) { - int c2 = q[i]; - if (c2 == '|') { - if (i == len) + if (q) { + if (!len) { + /* match the empty string against || only */ + while (*q) { + if (*q++ == '|' && *q == '|') return 1; - break; } - if (c2 == '\0') { - /* match the empty string against || only */ - return (len > 0 && i == len); - } - if (c2 == s[i++] && i <= len) - continue; - for (q += i;;) { - c2 = *q++; - if (c2 == '\0') - return 0; - if (c2 == '|') - break; - } - break; - } - } -} - -#if 0 -/* find a word in a list using '|' as separator */ -int strfind(const char *keytable, const char *str) -{ - int c, len; - const char *p; - - if (!keytable) - return 0; - - c = *str; - len = strlen(str); - /* need to special case the empty string */ - if (len == 0) - return strstr(keytable, "||") != NULL; - - /* initial and trailing | are optional */ - /* they do not cause the empty string to match */ - for (p = keytable;;) { - if (!memcmp(p, str, len) && (p[len] == '|' || p[len] == '\0')) - return 1; - for (;;) { - p = strchr(p + 1, c); - if (!p) - return 0; - if (p[-1] == '|') - break; - } - } -} -#else -/* Search for the string s in '|' delimited list of strings */ -int strfind(const char *list, const char *s) -{ - const char *p, *q; - int c1, c2; - - q = list; - if (!q) - return 0; - - if (*s == '\0') { - /* special case the empty string: must match || in list */ - while (*q) { - if (q[0] == '|' && q[1] == '|') - return 1; - q++; - } - return 0; - } else { - scan: - p = s; - for (;;) { - c1 = *p++; - c2 = *q++; - if (c1 == '\0') { - if (c2 == '\0' || c2 == '|') - return 1; - goto skip; - } - if (c1 != c2) { - for (;;) { - if (c2 == '|') - goto scan; - - if (c2 == '\0') - return 0; - skip: - c2 = *q++; + } else { + while (*q) { + for (start = q, i = 0; *q && *q++ != '|'; i++) + continue; + if (i == len) { + for (j = 0; j < i && start[j] == s[j]; j++) + continue; + if (j == i) + return 1; } } } } + return 0; +} + +/* find a word in a list using '|' as separator */ +int strfind(const char *keytable, const char *str) { + return memfind(keytable, str, strlen(str)); } -#endif /* find a word in a list using '|' as separator, ignore case and "-_ ". */ int strxfind(const char *list, const char *s)