unit.rs 4.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139
  1. use assert_matches::assert_matches;
  2. use unicode_normalization::char::is_combining_mark;
  3. /// https://github.com/servo/rust-url/issues/373
  4. #[test]
  5. fn test_punycode_prefix_with_length_check() {
  6. let config = idna::Config::default()
  7. .verify_dns_length(true)
  8. .check_hyphens(true)
  9. .use_std3_ascii_rules(true);
  10. assert!(config.to_ascii("xn--").is_err());
  11. assert!(config.to_ascii("xn---").is_err());
  12. assert!(config.to_ascii("xn-----").is_err());
  13. assert!(config.to_ascii("xn--.").is_err());
  14. assert!(config.to_ascii("xn--...").is_err());
  15. assert!(config.to_ascii(".xn--").is_err());
  16. assert!(config.to_ascii("...xn--").is_err());
  17. assert!(config.to_ascii("xn--.xn--").is_err());
  18. assert!(config.to_ascii("xn--.example.org").is_err());
  19. }
  20. /// https://github.com/servo/rust-url/issues/373
  21. #[test]
  22. fn test_punycode_prefix_without_length_check() {
  23. let config = idna::Config::default()
  24. .verify_dns_length(false)
  25. .check_hyphens(true)
  26. .use_std3_ascii_rules(true);
  27. assert_eq!(config.to_ascii("xn--").unwrap(), "");
  28. assert!(config.to_ascii("xn---").is_err());
  29. assert!(config.to_ascii("xn-----").is_err());
  30. assert_eq!(config.to_ascii("xn--.").unwrap(), ".");
  31. assert_eq!(config.to_ascii("xn--...").unwrap(), "...");
  32. assert_eq!(config.to_ascii(".xn--").unwrap(), ".");
  33. assert_eq!(config.to_ascii("...xn--").unwrap(), "...");
  34. assert_eq!(config.to_ascii("xn--.xn--").unwrap(), ".");
  35. assert_eq!(config.to_ascii("xn--.example.org").unwrap(), ".example.org");
  36. }
  37. // http://www.unicode.org/reports/tr46/#Table_Example_Processing
  38. #[test]
  39. fn test_examples() {
  40. let mut codec = idna::Idna::default();
  41. let mut out = String::new();
  42. assert_matches!(codec.to_unicode("Bloß.de", &mut out), Ok(()));
  43. assert_eq!(out, "bloß.de");
  44. out.clear();
  45. assert_matches!(codec.to_unicode("xn--blo-7ka.de", &mut out), Ok(()));
  46. assert_eq!(out, "bloß.de");
  47. out.clear();
  48. assert_matches!(codec.to_unicode("u\u{308}.com", &mut out), Ok(()));
  49. assert_eq!(out, "ü.com");
  50. out.clear();
  51. assert_matches!(codec.to_unicode("xn--tda.com", &mut out), Ok(()));
  52. assert_eq!(out, "ü.com");
  53. out.clear();
  54. assert_matches!(codec.to_unicode("xn--u-ccb.com", &mut out), Err(_));
  55. out.clear();
  56. assert_matches!(codec.to_unicode("a⒈com", &mut out), Err(_));
  57. out.clear();
  58. assert_matches!(codec.to_unicode("xn--a-ecp.ru", &mut out), Err(_));
  59. out.clear();
  60. assert_matches!(codec.to_unicode("xn--0.pt", &mut out), Err(_));
  61. out.clear();
  62. assert_matches!(codec.to_unicode("日本語。JP", &mut out), Ok(()));
  63. assert_eq!(out, "日本語.jp");
  64. out.clear();
  65. assert_matches!(codec.to_unicode("☕.us", &mut out), Ok(()));
  66. assert_eq!(out, "☕.us");
  67. }
  68. #[test]
  69. fn test_v5() {
  70. let config = idna::Config::default()
  71. .verify_dns_length(true)
  72. .use_std3_ascii_rules(true);
  73. // IdnaTest:784 蔏。𑰺
  74. assert!(is_combining_mark('\u{11C3A}'));
  75. assert!(config.to_ascii("\u{11C3A}").is_err());
  76. assert!(config.to_ascii("\u{850f}.\u{11C3A}").is_err());
  77. assert!(config.to_ascii("\u{850f}\u{ff61}\u{11C3A}").is_err());
  78. }
  79. #[test]
  80. fn test_v8_bidi_rules() {
  81. let config = idna::Config::default()
  82. .verify_dns_length(true)
  83. .use_std3_ascii_rules(true);
  84. assert_eq!(config.to_ascii("abc").unwrap(), "abc");
  85. assert_eq!(config.to_ascii("123").unwrap(), "123");
  86. assert_eq!(config.to_ascii("אבּג").unwrap(), "xn--kdb3bdf");
  87. assert_eq!(config.to_ascii("ابج").unwrap(), "xn--mgbcm");
  88. assert_eq!(config.to_ascii("abc.ابج").unwrap(), "abc.xn--mgbcm");
  89. assert_eq!(config.to_ascii("אבּג.ابج").unwrap(), "xn--kdb3bdf.xn--mgbcm");
  90. // Bidi domain names cannot start with digits
  91. assert!(config.to_ascii("0a.\u{05D0}").is_err());
  92. assert!(config.to_ascii("0à.\u{05D0}").is_err());
  93. // Bidi chars may be punycode-encoded
  94. assert!(config.to_ascii("xn--0ca24w").is_err());
  95. }
  96. #[test]
  97. fn emoji_domains() {
  98. // HOT BEVERAGE is allowed here...
  99. let config = idna::Config::default()
  100. .verify_dns_length(true)
  101. .use_std3_ascii_rules(true);
  102. assert_eq!(config.to_ascii("☕.com").unwrap(), "xn--53h.com");
  103. // ... but not here
  104. let config = idna::Config::default()
  105. .verify_dns_length(true)
  106. .use_std3_ascii_rules(true)
  107. .use_idna_2008_rules(true);
  108. let error = format!("{:?}", config.to_ascii("☕.com").unwrap_err());
  109. assert!(error.contains("disallowed_in_idna_2008"));
  110. }
  111. #[test]
  112. fn unicode_before_delimiter() {
  113. let config = idna::Config::default();
  114. assert!(config.to_ascii("xn--f\u{34a}-PTP").is_err());
  115. }