Refuse to save a script we only partly read
The transport fix stops the truncation that caused #76, but the save path had no answer for a baseline that arrives incomplete. It is neither unknown nor empty, so every existing guard passes it through: it parses into a shorter rule list that looks exactly like a script with fewer rules, and saving writes that back over the real one. Check the script against the shape the generator emits instead. Every rule comment parses, every enabled rule has an if and a closed body under it, every block ends with a blank line. Structural rather than a re-serialize-and-compare, so a script written by an older version whose serializer differed is still editable. The rule editor reports a short script as unreadable rather than showing the rules that happened to parse, since a list that looks complete over a script that is not is the most dangerous thing it could offer. A cut at the end of a complete rule block is still a valid shorter script and cannot be told apart from one; that residual is the proxy's to cover.
This commit is contained in:
@@ -45,7 +45,7 @@ const RULE_MIME = "application/x-ihasmail-sieve-rule";
|
||||
|
||||
function RulesEditor() {
|
||||
const sieve = useSieve();
|
||||
const { script, rules, content } = sieve.rules();
|
||||
const { script, rules, content, damage } = sieve.rules();
|
||||
const [local, setLocal] = useState<SieveRule[] | null>(null);
|
||||
const [editing, setEditing] = useState<SieveRule | null>(null);
|
||||
const [saving, setSaving] = useState(false);
|
||||
@@ -80,6 +80,19 @@ function RulesEditor() {
|
||||
}
|
||||
};
|
||||
|
||||
// Before the hand-written branch: a script that arrived in part is not a
|
||||
// script someone chose to write themselves, and the way out of it is a reload
|
||||
// rather than the "start with rules" button below, which would write over it.
|
||||
if (damage) {
|
||||
return (
|
||||
<div className="warn-box">
|
||||
<div className="row gap-8" style={{ marginBottom: 8 }}><AlertTriangle size={18} /> <b>Only part of your filter script arrived.</b></div>
|
||||
<p style={{ margin: "0 0 8px" }}>It {damage}, so the rules in it can't be shown or edited — saving what did arrive would write it back over the rest. Reload the page to try again. Your rules are still on the server; nothing here has changed them.</p>
|
||||
<button className="btn" onClick={() => window.location.reload()}>Reload</button>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
if (rules === null) {
|
||||
return (
|
||||
<div className="warn-box">
|
||||
|
||||
Reference in New Issue
Block a user