|
| 1 | +#![no_main] |
| 2 | + |
| 3 | +#[macro_use] |
| 4 | +extern crate libfuzzer_sys; |
| 5 | + |
| 6 | +use unicode_normalization::{ |
| 7 | + is_nfc, is_nfc_quick, is_nfc_stream_sa
10000
fe, is_nfc_stream_safe_quick, is_nfd, is_nfd_quick, |
| 8 | + is_nfd_stream_safe, is_nfd_stream_safe_quick, is_nfkc, is_nfkc_quick, is_nfkd, is_nfkd_quick, |
| 9 | + IsNormalized, UnicodeNormalization, |
| 10 | +}; |
| 11 | + |
| 12 | +fn from_bool(is_normalized: bool) -> IsNormalized { |
| 13 | + if is_normalized { |
| 14 | + IsNormalized::Yes |
| 15 | + } else { |
| 16 | + IsNormalized::No |
| 17 | + } |
| 18 | +} |
| 19 | + |
| 20 | +fuzz_target!(|input: String| { |
| 21 | + // The full predicates imply the quick predicates. |
| 22 | + assert!(is_nfc_quick(input.chars()) != from_bool(!is_nfc(&input))); |
| 23 | + assert!(is_nfd_quick(input.chars()) != from_bool(!is_nfd(&input))); |
| 24 | + assert!(is_nfkc_quick(input.chars()) != from_bool(!is_nfkc(&input))); |
| 25 | + assert!(is_nfkd_quick(input.chars()) != from_bool(!is_nfkd(&input))); |
| 26 | + assert!(is_nfc_stream_safe_quick(input.chars()) != from_bool(!is_nfc_stream_safe(&input))); |
| 27 | + assert!(is_nfd_stream_safe_quick(input.chars()) != from_bool(!is_nfd_stream_safe(&input))); |
| 28 | + |
| 29 | + // Check NFC, NFD, NFKC, and NFKD normalization. |
| 30 | + let nfc = input.chars().nfc().collect::<String>(); |
| 31 | + assert_eq!(nfc.is_empty(), input.is_empty()); |
| 32 | + assert_ne!(is_nfc_quick(nfc.chars()), IsNormalized::No); |
| 33 | + assert!(is_nfc(&nfc)); |
| 34 | + |
| 35 | + let nfd = input.chars().nfd().collect::<String>(); |
| 36 | + assert!(nfd.len() >= nfc.len()); |
| 37 | + assert_ne!(is_nfd_quick(nfd.chars()), IsNormalized::No); |
| 38 | + assert!(is_nfd(&nfd)); |
| 39 | + |
| 40 | + let nfkc = input.chars().nfkc().collect::<String>(); |
| 41 | + assert_eq!(nfkc.is_empty(), input.is_empty()); |
| 42 | + assert_ne!(is_nfkc_quick(nfkc.chars()), IsNormalized::No); |
| 43 | + assert!(is_nfkc(&nfkc)); |
| 44 | + |
| 45 | + let nfkd = input.chars().nfkd().collect::<String>(); |
| 46 | + assert!(nfkd.len() >= nfkc.len()); |
| 47 | + assert_ne!(is_nfkd_quick(nfkd.chars()), IsNormalized::No); |
| 48 | + assert!(is_nfkd(&nfkd)); |
| 49 | + |
| 50 | + // Check stream-safe. |
| 51 | + let nfc_ss = nfc.chars().stream_safe().collect::<String>(); |
| 52 | + assert!(nfc_ss.len() >= nfc.len()); |
| 53 | + assert_ne!(is_nfc_stream_safe_quick(nfc_ss.chars()), IsNormalized::No); |
| 54 | + assert!(is_nfc_stream_safe(&nfc_ss)); |
| 55 | + |
| 56 | + let nfd_ss = nfd.chars().stream_safe().collect::<String>(); |
| 57 | + assert!(nfd_ss.len() >= nfd.len()); |
| 58 | + assert_ne!(is_nfd_stream_safe_quick(nfd_ss.chars()), IsNormalized::No); |
| 59 | + assert!(is_nfd_stream_safe(&nfd_ss)); |
| 60 | + |
| 61 | + // Check that NFC and NFD preserve stream-safe. |
| 62 | + let ss_nfc = input.chars().stream_safe().nfc().collect::<String>(); |
| 63 | + assert_eq!(ss_nfc.is_empty(), input.is_empty()); |
| 64 | + assert_ne!(is_nfc_stream_safe_quick(ss_nfc.chars()), IsNormalized::No); |
| 65 | + assert!(is_nfc_stream_safe(&ss_nfc)); |
| 66 | + |
| 67 | + let ss_nfd = input.chars().stream_safe().nfd().collect::<String>(); |
| 68 | + assert_eq!(ss_nfd.is_empty(), input.is_empty()); |
| 69 | + assert_ne!(is_nfd_stream_safe_quick(ss_nfd.chars()), IsNormalized::No); |
| 70 | + assert!(is_nfd_stream_safe(&ss_nfd)); |
| 71 | +}); |
0 commit comments