Reject unclosed quotes in heredoc operator
@@ -1814,7 +1814,9 @@ | ||
1814 | 1814 | return buf; |
1815 | 1815 | } |
1816 | 1816 | |
1817 | -/* Removes quotes (', ", \). The result is a newly malloced string. */ | |
1817 | +/* Removes quotes (', ", \). | |
1818 | + * The result is a newly malloced string if successful. | |
1819 | + * Returns NULL if there is an unclosed quote. */ | |
1818 | 1820 | wchar_t *unquote(const wchar_t *s) |
1819 | 1821 | { |
1820 | 1822 | bool indq = false; |
@@ -1823,13 +1825,19 @@ | ||
1823 | 1825 | for (;;) { |
1824 | 1826 | switch (*s) { |
1825 | 1827 | case L'\0': |
1828 | + if (indq) { | |
1829 | + wb_destroy(&buf); | |
1830 | + return NULL; | |
1831 | + } | |
1826 | 1832 | return wb_towcs(&buf); |
1827 | 1833 | case L'\'': |
1828 | 1834 | if (indq) |
1829 | 1835 | goto default_case; |
1830 | 1836 | add_sq(&s, &buf, false); |
1831 | - if (*s == L'\0') | |
1832 | - return wb_towcs(&buf); | |
1837 | + if (*s == L'\0') { | |
1838 | + wb_destroy(&buf); | |
1839 | + return NULL; | |
1840 | + } | |
1833 | 1841 | assert(*s == L'\''); |
1834 | 1842 | break; |
1835 | 1843 | case L'"': |
@@ -3165,6 +3165,12 @@ | ||
3165 | 3165 | void read_heredoc_contents_without_expansion(parsestate_T *ps, redir_T *r) |
3166 | 3166 | { |
3167 | 3167 | wchar_t *eoc = unquote(r->rd_hereend); // end-of-contents marker |
3168 | + if (eoc == NULL) { | |
3169 | + serror(ps, Ngt("the end-of-here-document indicator " | |
3170 | + "is not properly quoted")); | |
3171 | + return; | |
3172 | + } | |
3173 | + | |
3168 | 3174 | bool skiptab = (r->rd_type == RT_HERERT); |
3169 | 3175 | xwcsbuf_T buf; |
3170 | 3176 |
@@ -1337,7 +1337,7 @@ | ||
1337 | 1337 | { |
1338 | 1338 | if (w != NULL && w->next == NULL && w->wu_type == WT_STRING) { |
1339 | 1339 | wchar_t *cmdname = unquote(w->wu_string); |
1340 | - if (wcschr(cmdname, L'/') == NULL) { | |
1340 | + if (cmdname != NULL && wcschr(cmdname, L'/') == NULL) { | |
1341 | 1341 | char *mbsname = malloc_wcstombs(cmdname); |
1342 | 1342 | get_command_path(mbsname, false); |
1343 | 1343 | free(mbsname); |