diff --git a/fish-rust/src/common.rs b/fish-rust/src/common.rs index 73e76a0c8..7725e6e2f 100644 --- a/fish-rust/src/common.rs +++ b/fish-rust/src/common.rs @@ -979,6 +979,9 @@ pub fn read_unquoted_escape( } if let Some(c) = result_char_or_none { + if fish_reserved_codepoint(c) { + return None; + } result.push(c); } @@ -1134,9 +1137,7 @@ pub fn str2wcstring(inp: &[u8]) -> WString { Some(codepoint) => { c = codepoint; // Determine whether to encode this character with our crazy scheme. - (c >= ENCODE_DIRECT_BASE && c < ENCODE_DIRECT_END) - || - c == INTERNAL_SEPARATOR + fish_reserved_codepoint(c) || // Incomplete sequence. ret == 0_usize.wrapping_sub(2) diff --git a/src/common.cpp b/src/common.cpp index 60319dfed..f12c47ed2 100644 --- a/src/common.cpp +++ b/src/common.cpp @@ -328,12 +328,10 @@ static wcstring str2wcs_internal(const char *in, const size_t in_len) { } else { ret = std::mbrtowc(&wc, &in[in_pos], in_len - in_pos, &state); // Determine whether to encode this character with our crazy scheme. - if (wc >= ENCODE_DIRECT_BASE && wc < ENCODE_DIRECT_BASE + 256) { + if (fish_reserved_codepoint(wc)) { use_encode_direct = true; } else if ((wc >= 0xD800 && wc <= 0xDFFF) || static_cast(wc) >= 0x110000) { use_encode_direct = true; - } else if (wc == INTERNAL_SEPARATOR) { - use_encode_direct = true; } else if (ret == static_cast(-2)) { // Incomplete sequence. use_encode_direct = true; diff --git a/tests/checks/basic.fish b/tests/checks/basic.fish index 9d913de6c..eedc04035 100644 --- a/tests/checks/basic.fish +++ b/tests/checks/basic.fish @@ -612,6 +612,14 @@ $fish -c begin echo $status # CHECK: 127 +$fish -c 'echo \ufdd2"fart"' +# CHECKERR: fish: Invalid token '\ufdd2"fart"' +# CHECKERR: echo \ufdd2"fart" +# CHECKERR: ^~~~~~~~~~~^ + +echo (printf '\ufdd2foo') | string escape +# CHECK: \Xef\Xb7\X92foo + printf '%s\n' "#!/bin/sh" 'echo $0' > $tmpdir/argv0.sh chmod +x $tmpdir/argv0.sh cd $tmpdir