mirror of
https://github.com/storytold/gridcraft.git
synced 2026-11-08 19:40:19 -06:00
Math: refuse computed environment names in the alignat pair cap
A name such as align\@char{97}t reads as alignat to the parser but split at
the first } looked like another environment, so the pair limit was skipped.
Names that contain a backslash or brace, or do not close in the window, are
now refused like an unreadable count.
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Sonnet 5.5
parent
f077b9ef36
commit
225496e544
+19
-1
@@ -392,6 +392,7 @@ const MAX_ALIGNAT_PAIRS: usize = 50;
|
||||
/// N of `{alignat}{N}`, `{alignat*}{N}` or `{alignedat}{N}` at the start of `rest` (just after
|
||||
/// `\begin`). `usize::MAX` when the count is present but is not a plain digit string RaTeX reads
|
||||
/// the same way (too long, or hidden by a comment, inner spaces or a macro): refused, not skipped.
|
||||
/// An environment name that is computed (contains `\` or `{`) is refused the same way.
|
||||
///
|
||||
/// RaTeX reads the environment name and the count through its lexer, which drops comments and
|
||||
/// spaces, so they are dropped here too before the two groups are compared.
|
||||
@@ -414,7 +415,16 @@ fn alignat_columns(rest: &str) -> Option<usize> {
|
||||
Some(c) => kept.push(c),
|
||||
}
|
||||
}
|
||||
let (name, after) = kept.strip_prefix('{')?.split_once('}')?;
|
||||
let group = kept.strip_prefix('{')?;
|
||||
// A name that does not close inside the window cannot be read, so it is refused.
|
||||
let Some((name, after)) = group.split_once('}') else {
|
||||
return Some(usize::MAX);
|
||||
};
|
||||
// A computed name (`align\@char{97}t` reads as `alignat`) cannot be resolved here: refused
|
||||
// too. Every real environment name is letters, optionally with a trailing `*`.
|
||||
if name.contains(['\\', '{']) {
|
||||
return Some(usize::MAX);
|
||||
}
|
||||
if !matches!(name, "alignat" | "alignat*" | "alignedat") {
|
||||
return None;
|
||||
}
|
||||
@@ -755,6 +765,14 @@ mod tests {
|
||||
] {
|
||||
assert!(check_caps(hidden).is_err_and(|e| e.message.contains("matrix cells")), "{hidden}");
|
||||
}
|
||||
// A computed environment name reads as `alignat` to the parser, so it is capped too.
|
||||
for name in ["align\\@char{97}t", "alignedat\\relax", "al\\@char{105}gnat*"] {
|
||||
let over = format!("\\begin{{{name}}}{{51}}a\\end{{alignat}}");
|
||||
assert!(check_caps(&over).is_err_and(|e| e.message.contains("matrix cells")), "{over}");
|
||||
}
|
||||
let long = format!("\\begin{{{}}}{{51}}a\\end{{alignat}}", "a".repeat(80));
|
||||
assert!(check_caps(&long).is_err_and(|e| e.message.contains("matrix cells")));
|
||||
assert!(check_caps("\\begin{alignat}{50}a\\end{alignat}").is_ok());
|
||||
assert!(check_caps("\\begin{alignedat} {2} % two pairs\na&b&c&d\\end{alignedat}").is_ok());
|
||||
assert!(layout("\\begin{CD}A @>f>> B \\\\ @VVV @VVV \\\\ C @>>> D\\end{CD}").is_ok());
|
||||
assert!(check_caps("\\operatorname{curl} 50\\%").is_ok());
|
||||
|
||||
Reference in New Issue
Block a user