From 6596d91c8264a8a0705736003c129a4422e91564 Mon Sep 17 00:00:00 2001 From: Konrad Borowski Date: Sat, 10 May 2014 17:13:08 +0200 Subject: [PATCH 1/3] Fix prompt under Windows. The fix is obviously a hack caused by that NOT_A_WCHAR doesn't fit in wchar_t. Better fix would be nice. --- common.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/common.cpp b/common.cpp index ac0181d36..f02626d3b 100644 --- a/common.cpp +++ b/common.cpp @@ -1619,8 +1619,9 @@ static bool unescape_string_internal(const wchar_t * const input, const size_t i } } + wchar_t not_a_wchar = NOT_A_WCHAR; /* Now maybe append the char */ - if (to_append != NOT_A_WCHAR) + if (to_append != not_a_wchar) { result.push_back(to_append); } From 3225d7e169a9edb2f470c26989e7bc8e0d0355ce Mon Sep 17 00:00:00 2001 From: David Adam Date: Mon, 28 Apr 2014 23:37:02 +0800 Subject: [PATCH 2/3] avoid symlink attacks in __fish_print_packages and spawning fishd * use $XDG_CACHE_HOME for __fish_print_packages completion caches * when starting fishd, redirect fishd output to /dev/null, not a predictable path Fix for CVE-2014-3219. Closes #1440. --- env.cpp | 2 +- share/functions/__fish_print_packages.fish | 12 +++++++++--- 2 files changed, 10 insertions(+), 4 deletions(-) diff --git a/env.cpp b/env.cpp index ff62a53f6..086f181ab 100644 --- a/env.cpp +++ b/env.cpp @@ -58,7 +58,7 @@ #include "fish_version.h" /** Command used to start fishd */ -#define FISHD_CMD L"fishd ^ /tmp/fishd.log.%s" +#define FISHD_CMD L"fishd ^ /dev/null" // Version for easier debugging //#define FISHD_CMD L"fishd" diff --git a/share/functions/__fish_print_packages.fish b/share/functions/__fish_print_packages.fish index ec812a64e..6755dd6ae 100644 --- a/share/functions/__fish_print_packages.fish +++ b/share/functions/__fish_print_packages.fish @@ -12,6 +12,12 @@ function __fish_print_packages #Get the word 'Package' in the current language set -l package (_ Package) + # Set up cache directory + if test -z "$XDG_CACHE_HOME" + set XDG_CACHE_HOME $HOME/.cache + end + mkdir -m 700 -p $XDG_CACHE_HOME + if type -f apt-cache >/dev/null # Do not generate the cache as apparently sometimes this is slow. # http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=547550 @@ -31,7 +37,7 @@ function __fish_print_packages # Caches for 5 minutes if type -f pacman >/dev/null - set cache_file /tmp/.pac-cache.$USER + set cache_file $XDG_CACHE_HOME/.pac-cache.$USER if test -f $cache_file cat $cache_file set age (math (date +%s) - (stat -c '%Y' $cache_file)) @@ -51,7 +57,7 @@ function __fish_print_packages # If the cache is less than six hours old, we do not recalculate it - set cache_file /tmp/.yum-cache.$USER + set cache_file $XDG_CACHE_HOME/.yum-cache.$USER if test -f $cache_file cat $cache_file set age (math (date +%s) - (stat -c '%Y' $cache_file)) @@ -73,7 +79,7 @@ function __fish_print_packages # If the cache is less than five minutes old, we do not recalculate it - set cache_file /tmp/.rpm-cache.$USER + set cache_file $XDG_CACHE_HOME/.rpm-cache.$USER if test -f $cache_file cat $cache_file set age (math (date +%s) - (stat -c '%Y' $cache_file)) From c7aca5cc35d0f08d03ea05a4a8609e3f8239944b Mon Sep 17 00:00:00 2001 From: ridiculousfish Date: Wed, 14 May 2014 13:30:41 +0800 Subject: [PATCH 3/3] Hopefully better fix for prompt under Windows. Things that may store NOT_A_WCHAR must be wint_t, not wchar_t --- common.cpp | 87 +++++++++++++++++++++++++++++------------------------- 1 file changed, 46 insertions(+), 41 deletions(-) diff --git a/common.cpp b/common.cpp index f02626d3b..9c0db257b 100644 --- a/common.cpp +++ b/common.cpp @@ -72,7 +72,7 @@ parts of fish. #include "util.cpp" #include "fallback.cpp" -#define NOT_A_WCHAR WEOF +#define NOT_A_WCHAR (static_cast(WEOF)) struct termios shell_modes; @@ -1137,8 +1137,8 @@ static size_t read_unquoted_escape(const wchar_t *input, wcstring *result, bool return 0; } - /* Here's the character we'll ultimately append. Note that L'\0' is a valid thing to append. */ - wchar_t result_char = NOT_A_WCHAR; + /* Here's the character we'll ultimately append, or NOT_A_WCHAR for none. Note that L'\0' is a valid thing to append. */ + wint_t result_char_or_none = NOT_A_WCHAR; bool errored = false; size_t in_pos = 1; //in_pos always tracks the next character to read (and therefore the number of characters read so far) @@ -1240,7 +1240,7 @@ static size_t read_unquoted_escape(const wchar_t *input, wcstring *result, bool if (res <= max_val) { - result_char = (wchar_t)((byte_literal ? ENCODE_DIRECT_BASE : 0)+res); + result_char_or_none = (wchar_t)((byte_literal ? ENCODE_DIRECT_BASE : 0)+res); } else { @@ -1253,14 +1253,14 @@ static size_t read_unquoted_escape(const wchar_t *input, wcstring *result, bool /* \a means bell (alert) */ case L'a': { - result_char = L'\a'; + result_char_or_none = L'\a'; break; } /* \b means backspace */ case L'b': { - result_char = L'\b'; + result_char_or_none = L'\b'; break; } @@ -1270,11 +1270,11 @@ static size_t read_unquoted_escape(const wchar_t *input, wcstring *result, bool const wchar_t sequence_char = input[in_pos++]; if (sequence_char >= L'a' && sequence_char <= (L'a'+32)) { - result_char = sequence_char-L'a'+1; + result_char_or_none = sequence_char-L'a'+1; } else if (sequence_char >= L'A' && sequence_char <= (L'A'+32)) { - result_char = sequence_char-L'A'+1; + result_char_or_none = sequence_char-L'A'+1; } else { @@ -1286,7 +1286,7 @@ static size_t read_unquoted_escape(const wchar_t *input, wcstring *result, bool /* \x1b means escape */ case L'e': { - result_char = L'\x1b'; + result_char_or_none = L'\x1b'; break; } @@ -1295,7 +1295,7 @@ static size_t read_unquoted_escape(const wchar_t *input, wcstring *result, bool */ case L'f': { - result_char = L'\f'; + result_char_or_none = L'\f'; break; } @@ -1304,7 +1304,7 @@ static size_t read_unquoted_escape(const wchar_t *input, wcstring *result, bool */ case L'n': { - result_char = L'\n'; + result_char_or_none = L'\n'; break; } @@ -1313,7 +1313,7 @@ static size_t read_unquoted_escape(const wchar_t *input, wcstring *result, bool */ case L'r': { - result_char = L'\r'; + result_char_or_none = L'\r'; break; } @@ -1322,7 +1322,7 @@ static size_t read_unquoted_escape(const wchar_t *input, wcstring *result, bool */ case L't': { - result_char = L'\t'; + result_char_or_none = L'\t'; break; } @@ -1331,14 +1331,14 @@ static size_t read_unquoted_escape(const wchar_t *input, wcstring *result, bool */ case L'v': { - result_char = L'\v'; + result_char_or_none = L'\v'; break; } /* If a backslash is followed by an actual newline, swallow them both */ case L'\n': { - result_char = NOT_A_WCHAR; + result_char_or_none = NOT_A_WCHAR; break; } @@ -1346,13 +1346,16 @@ static size_t read_unquoted_escape(const wchar_t *input, wcstring *result, bool { if (unescape_special) result->push_back(INTERNAL_SEPARATOR); - result_char = c; + result_char_or_none = c; break; } } - if (! errored && result_char != NOT_A_WCHAR) + if (! errored && result_char_or_none != NOT_A_WCHAR) { + wchar_t result_char = static_cast(result_char_or_none); + // if result_char is not NOT_A_WCHAR, it must be a valid wchar + assert((wint_t)result_char == result_char_or_none); result->push_back(result_char); } return errored ? 0 : in_pos; @@ -1382,7 +1385,7 @@ static bool unescape_string_internal(const wchar_t * const input, const size_t i { const wchar_t c = input[input_position]; /* Here's the character we'll append to result, or NOT_A_WCHAR to suppress it */ - wchar_t to_append = c; + wint_t to_append_or_none = c; if (mode == mode_unquoted) { @@ -1404,7 +1407,7 @@ static bool unescape_string_internal(const wchar_t * const input, const size_t i input_position += escape_chars - 1; } /* We've already appended, don't append anything else */ - to_append = NOT_A_WCHAR; + to_append_or_none = NOT_A_WCHAR; break; } @@ -1412,7 +1415,7 @@ static bool unescape_string_internal(const wchar_t * const input, const size_t i { if (unescape_special && (input_position == 0)) { - to_append = HOME_DIRECTORY; + to_append_or_none = HOME_DIRECTORY; } break; } @@ -1421,7 +1424,7 @@ static bool unescape_string_internal(const wchar_t * const input, const size_t i { if (unescape_special && (input_position == 0)) { - to_append = PROCESS_EXPAND; + to_append_or_none = PROCESS_EXPAND; } break; } @@ -1435,11 +1438,11 @@ static bool unescape_string_internal(const wchar_t * const input, const size_t i { assert(result.size() > 0); result.resize(result.size() - 1); - to_append = ANY_STRING_RECURSIVE; + to_append_or_none = ANY_STRING_RECURSIVE; } else { - to_append = ANY_STRING; + to_append_or_none = ANY_STRING; } } break; @@ -1449,7 +1452,7 @@ static bool unescape_string_internal(const wchar_t * const input, const size_t i { if (unescape_special) { - to_append = ANY_CHAR; + to_append_or_none = ANY_CHAR; } break; } @@ -1458,7 +1461,7 @@ static bool unescape_string_internal(const wchar_t * const input, const size_t i { if (unescape_special) { - to_append = VARIABLE_EXPAND; + to_append_or_none = VARIABLE_EXPAND; } break; } @@ -1468,7 +1471,7 @@ static bool unescape_string_internal(const wchar_t * const input, const size_t i if (unescape_special) { bracket_count++; - to_append = BRACKET_BEGIN; + to_append_or_none = BRACKET_BEGIN; } break; } @@ -1478,7 +1481,7 @@ static bool unescape_string_internal(const wchar_t * const input, const size_t i if (unescape_special) { bracket_count--; - to_append = BRACKET_END; + to_append_or_none = BRACKET_END; } break; } @@ -1488,7 +1491,7 @@ static bool unescape_string_internal(const wchar_t * const input, const size_t i /* If the last character was a separator, then treat this as a literal comma */ if (unescape_special && bracket_count > 0 && string_last_char(result) != BRACKET_SEP) { - to_append = BRACKET_SEP; + to_append_or_none = BRACKET_SEP; } break; } @@ -1496,14 +1499,14 @@ static bool unescape_string_internal(const wchar_t * const input, const size_t i case L'\'': { mode = mode_single_quotes; - to_append = unescape_special ? INTERNAL_SEPARATOR : NOT_A_WCHAR; + to_append_or_none = unescape_special ? INTERNAL_SEPARATOR : NOT_A_WCHAR; break; } case L'\"': { mode = mode_double_quotes; - to_append = unescape_special ? INTERNAL_SEPARATOR : NOT_A_WCHAR; + to_append_or_none = unescape_special ? INTERNAL_SEPARATOR : NOT_A_WCHAR; break; } } @@ -1518,7 +1521,7 @@ static bool unescape_string_internal(const wchar_t * const input, const size_t i case '\\': case L'\'': { - to_append = input[input_position + 1]; + to_append_or_none = input[input_position + 1]; input_position += 1; /* Skip over the backslash */ break; } @@ -1535,7 +1538,7 @@ static bool unescape_string_internal(const wchar_t * const input, const size_t i // 'We may ever escape a NULL character, but still appending a \ in case I am wrong.' // Not sure what it means or the importance of this input_position += 1; /* Skip over the backslash */ - to_append = L'\\'; + to_append_or_none = L'\\'; } } break; @@ -1549,7 +1552,7 @@ static bool unescape_string_internal(const wchar_t * const input, const size_t i } else if (c == L'\'') { - to_append = unescape_special ? INTERNAL_SEPARATOR : NOT_A_WCHAR; + to_append_or_none = unescape_special ? INTERNAL_SEPARATOR : NOT_A_WCHAR; mode = mode_unquoted; } } @@ -1560,7 +1563,7 @@ static bool unescape_string_internal(const wchar_t * const input, const size_t i case L'"': { mode = mode_unquoted; - to_append = unescape_special ? INTERNAL_SEPARATOR : NOT_A_WCHAR; + to_append_or_none = unescape_special ? INTERNAL_SEPARATOR : NOT_A_WCHAR; break; } @@ -1576,7 +1579,7 @@ static bool unescape_string_internal(const wchar_t * const input, const size_t i } else { - to_append = L'\0'; + to_append_or_none = L'\0'; } } break; @@ -1585,7 +1588,7 @@ static bool unescape_string_internal(const wchar_t * const input, const size_t i case L'$': case '"': { - to_append = input[input_position + 1]; + to_append_or_none = input[input_position + 1]; input_position += 1; /* Skip over the backslash */ break; } @@ -1593,7 +1596,7 @@ static bool unescape_string_internal(const wchar_t * const input, const size_t i case '\n': { /* Swallow newline */ - to_append = NOT_A_WCHAR; + to_append_or_none = NOT_A_WCHAR; input_position += 1; /* Skip over the backslash */ break; } @@ -1611,7 +1614,7 @@ static bool unescape_string_internal(const wchar_t * const input, const size_t i { if (unescape_special) { - to_append = VARIABLE_EXPAND_SINGLE; + to_append_or_none = VARIABLE_EXPAND_SINGLE; } break; } @@ -1619,11 +1622,13 @@ static bool unescape_string_internal(const wchar_t * const input, const size_t i } } - wchar_t not_a_wchar = NOT_A_WCHAR; /* Now maybe append the char */ - if (to_append != not_a_wchar) + if (to_append_or_none != NOT_A_WCHAR) { - result.push_back(to_append); + wchar_t to_append_char = static_cast(to_append_or_none); + // if result_char is not NOT_A_WCHAR, it must be a valid wchar + assert((wint_t)to_append_char == to_append_or_none); + result.push_back(to_append_char); } }