Don't try to use partially-parsed colors on error

Historically, "fish_color_*" variables used a hand-written option
parser that would try to recover from invalid options.

Commit 037c1896d4 (Reuse wgetopt parsing for set_color for internal
colors, 2025-04-13) tried to preserve this recovering, but that
breaks WGetopter invariants.

I don't think this type of fallback is important, because
there's no reason we can't parse color variables (except maybe
forward-compatibility in future). Let's turn errors into the default
style; this should tell the user that their color is unsupported.

Fixes #12078
This commit is contained in:
Johannes Altmanninger
2025-11-18 19:22:51 +01:00
parent 64cb4398c6
commit c53b787339
2 changed files with 10 additions and 13 deletions

View File

@@ -19,6 +19,10 @@ For distributors and developers
-------------------------------
- ``fish_key_reader`` and ``fish_indent`` are now hardlinks to ``fish``.
Regression fixes:
-----------------
- (from 4.1.0) Crash on invalid colors variables (:issue:`12078`).
fish 4.2.1 (released November 13, 2025)
=======================================

View File

@@ -150,7 +150,8 @@ pub(crate) fn parse_text_face(arguments: &[WString]) -> SpecifiedTextFace {
use ParsedArgs::*;
match parse_text_face_and_options(&mut argv, /*is_builtin=*/ false) {
Ok(SetFace(specified_face)) => specified_face,
Ok(ResetFace) | Ok(PrintColors(_)) | Ok(PrintHelp) | Err(_) => unreachable!(),
Err(_) => Default::default(),
Ok(ResetFace) | Ok(PrintColors(_)) | Ok(PrintHelp) => unreachable!(),
}
}
@@ -248,10 +249,8 @@ pub(crate) fn parse_text_face_and_options<'argarray, 'args>(
UnderlineStyle::Dotted
} else if arg == "dashed" {
UnderlineStyle::Dashed
} else if is_builtin {
return Err(UnknownUnderlineStyle(arg));
} else {
continue;
return Err(UnknownUnderlineStyle(arg));
});
}
'c' => {
@@ -259,19 +258,13 @@ pub(crate) fn parse_text_face_and_options<'argarray, 'args>(
print_color_mode = true;
}
':' => {
if is_builtin {
return Err(MissingOptArg);
}
return Err(MissingOptArg);
}
';' => {
if is_builtin {
return Err(UnexpectedOptArg(w.wopt_index - 1));
}
return Err(UnexpectedOptArg(w.wopt_index - 1));
}
'?' => {
if is_builtin {
return Err(UnknownOption(w.wopt_index - 1));
}
return Err(UnknownOption(w.wopt_index - 1));
}
_ => unreachable!("unexpected retval from WGetopter"),
}