v3 : troisième relecture — une coquille n'inverse plus un sens ; retour à la version précédente
- Mot mal tapé = un seul glissement (une lettre ajoutée, retirée, ou deux voisines inversées), jamais au début du mot (préfixes : valide/invalide, limitée/illimitée), jamais une lettre remplacée (deux/dix, majorité/minorité), jamais sur un mot de négation ou de quantité, mots de 4 lettres au moins. - Parenthèses, crochets, « / » et tout ce qui est entre accents graves comptent comme le sens (ceil(N^(1/5)) → ceil(N^1/5) n'est plus une coquille). - Caractères invisibles (inversion du sens d'écriture, largeur nulle, BOM) refusés dans les textes, titres, traductions et motifs de signalement. - Déploiement : la version en service est gardée (image « previous ») ; un témoin marque le déploiement en cours ; « retablir » relance la maquette au premier déploiement, la version précédente ensuite ; la liste des conteneurs retirés n'est plus vidée par un pipeline annulé. - Tests : 59 Rust (dont 14 scénarios d'API, avec deux → dix sur E2 en vigueur et l'inversion bidi), e2e 12 / 12. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
@@ -59,6 +59,9 @@ async fn guarded(state: &AppState, user: &IdentityRow, proposal_id: &str) -> App
|
||||
}
|
||||
|
||||
fn check_text(title: &str, body: &str, needs_body: bool) -> AppResult<()> {
|
||||
if edit::has_hidden_controls(title) || edit::has_hidden_controls(body) {
|
||||
return Err(AppError::Invalid("hidden_characters"));
|
||||
}
|
||||
if title.trim().is_empty() || title.chars().count() > MAX_TITLE {
|
||||
return Err(AppError::Invalid("title"));
|
||||
}
|
||||
@@ -647,7 +650,7 @@ pub async fn signal(
|
||||
) -> AppResult<Json<serde_json::Value>> {
|
||||
let (p, st) = guarded(&state, &user, &id).await?;
|
||||
let reason = b.reason.trim();
|
||||
if reason.chars().count() < MIN_REASON || reason.chars().count() > MAX_REASON {
|
||||
if reason.chars().count() < MIN_REASON || reason.chars().count() > MAX_REASON || edit::has_hidden_controls(reason) {
|
||||
return Err(AppError::Invalid("reason"));
|
||||
}
|
||||
if b.target_id == id {
|
||||
|
||||
Reference in New Issue
Block a user