1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
//! # rtl-flip-detect
//!
//! Detect bidi-control characters that flip rendered direction.
//!
//! The classic attack: a filename `evil\u{202E}cod.exe` renders as
//! `evilexe.doc` because U+202E (RIGHT-TO-LEFT OVERRIDE) flips
//! everything after it. Same trick works inside any text the model
//! displays back, or a tool argument.
//!
//! This crate finds and strips those.
//!
//! Controls flagged:
//! - U+202A LRE, U+202B RLE, U+202D LRO, U+202E RLO
//! - U+202C PDF (pop directional formatting — could close an attacker's open)
//! - U+2066 LRI, U+2067 RLI, U+2068 FSI, U+2069 PDI
//!
//! ## Example
//!
//! ```
//! use rtl_flip_detect::{has_rtl_flip, strip_rtl_flips};
//! let evil = "evil\u{202E}cod.exe";
//! assert!(has_rtl_flip(evil));
//! assert_eq!(strip_rtl_flips(evil), "evilcod.exe");
//! ```
/// True when the input contains any bidi-control char that could flip
/// direction.
/// Return the byte positions of every bidi-control char in `s`.
/// Strip every bidi-control char from `s`.